/*
 *  AMGlobal.cpp
 *  AMPlugin
 *
 *  Created by Tiet Anh Vu on 5/30/12.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */

#include "VCPlugInHeaders.h"

// Interface Include
#include "ITreeViewMgr.h"
#include "IPalettePanelUtils.h"
#include "ITreeViewHierarchyAdapter.h"
#include "IStringListData.h"
#include "IPanelControlData.h"
#include "IScriptUtils.h"
#include "IStoryList.h"
#include "ISelectionUtils.h"

// General includes:
#include "StreamUtil.h"
#include "ISnippetExport.h"

// Project Include
#include "AMPID.h"
#include "AMGlobal.h"
#include "SDKFileHelper.h"
#include "ISnipRunSuite.h"
#include "textiterator.h"
#include "IIDMLComponentName.h"
#include "StringUtils.h"
#include "SnpTextModelHelper.h"
#include "DocWchUtils.h"
#include "SDKLayoutHelper.h"
#include "HTTPRequestHelper.h"
#include "AMPLogDataRecord.h"
#include "ITextControlData.h"
#include "IWidgetParent.h"
#include "IApplication.h"
#include "IDocumentList.h"
#include "AMPCAlert.h"
#include "AMPDocument.h"
#include "AMPLogCenter.h"
#include "CmdUtils.h"
#include "ICommand.h"
#include "IDocumentLayer.h"
#include "IItemLockData.h"
#include "IAutoLayoutPrefs.h"
#include "ILayerUtils.h"
#include "IPageItemLockSuite.h"
#include "TransformUtils.h"
#include "ILiveEditFacade.h"
#include <iostream>
using namespace std;

///+++++++++
// Interface includes
#include "ISubject.h"
#include "IControlView.h"
#include "ITreeViewController.h"
#include "IApplication.h"
#include "IDialogMgr.h"
#include "PMRect.h"
// General includes:
#include "CoreResTypes.h"
#include "LocaleSetting.h"
#include "RsrcSpec.h"
#include "IDocumentCommands.h"
#include "INewDocCmdData.h"
#include "IPageSizes.h"
#include "IPageList.h"
// General includes:
#include "ISpreadList.h"
#include "K2Vector.h"
#include "K2Assert.h"
#include "JSONHelper.h"
#include "IGeometry.h"
#include "IPageItemTypeUtils.h"
#include "PageItemScrapID.h" // kDeleteCmdBoss
#include "IGraphicFrameData.h"
#include "ITOPSplineData.h"
//#include "ITextFrameColumn.h"
//#include "ILayoutSelectionSuite.h"
//#include "ISelectionManager.h"
//#include "ITextSelectionSuite.h"
#include "IDocumentUtils.h"
#include "ISpread.h"
#include "ISysFileData.h"
#include "ITriStateControlData.h"
#include "Utils.h"
#include "UIDList.h"
#include "AMPIconFrameUpdate.h"
#include "ILinkedStoryModificationState.h"
#include "IPageItemVisibilityFacade.h"




///+++++++++
Magazine *g_Magazines;
textframes_t *g_TextFrames;
int g_Magazine_Count;
string g_SDK_WorkspaceDir; // format Macintosh HD:Users:vutiet:AMPInDesignPlugin
string g_System_WorkspaceDir; // format /Users/currentUserLogin/AMPInDesignPlugin
string g_Domain = "";
string g_Username = "";
string g_Password = "";
bool g_IsLoggedIn = FALSE;
//bool g_ShouldDownload = FALSE;
//bool b_SystemWait = FALSE;
bool g_TextSelected = FALSE;
bool g_PrevTextSelected = FALSE;
string g_SelectedTextFrameUID = "";
//string g_TextFramesID[1000];
int g_TextFrameCount = 0;
std::vector<images_t> g_ImageInfo;
std::vector<links_t> g_LinkInfo;
std::vector<assignee_links_t> g_AssigneeInfo;
std::vector<pt_assignStr> g_assignmentPtr;
vector<caption_t> g_captionImg;
//UIDRef g_PackageFrameRef;
//bool g_IsCheckOut = FALSE;
//bool g_IsIssueEnable = FALSE;

string g_System_logDirectory;
string g_SDK_logDirectory;
// Current id check out and check in
string g_Magazineid = "";
string g_Issueid = "";
string g_Pageid = "";
string g_Storyid = "";
string g_IDMLzip = "";
string g_Package_id ="";
string g_DocName="";
//string g_IDMLOpen = "";
//bool g_ShouldUpdateDocName = FALSE;
//bool shouldAssignDocName = FALSE;
string  g_Resolution = "";
string	n_mSessionConnection = "";
string	n_mSessionID = "";				// Session id :
int32	n_mSessionTimeOut;			// Session time out :
string	n_mSessionUserID = "";			// Session user id :
int32	n_mSessionCounterReset;
int32	n_mSessionTotalCounterReset;

string	g_Authentication = "";
// checked out stories
string g_CheckedOutStories = "";

// handling images
string g_ChosenStoryID = "";
string g_ChosenImagePath = "";
string g_ChosenImageName = "";
string g_pageNumberCheckOut = "";
string g_pageEditing = "";
string g_issueEditing = "";
//string g_IssueNumberCheckOut = "";
string g_pageCheckIn = "";
//int curImgPos = 0;
//string curNodeImgPath = "";
//string curNodeName = "";
int g_CurPreviewImgPos;
string g_CurPreviewImaPath;
string g_CurPreviewNodeName;
string g_ImagePreview;
//g_MembersPageInfo *g_MemberPageInfo;
string g_UnlockStories = ""; 
bool   g_ProxyEnable = FALSE;
bool   g_ProxyAuthEnable = FALSE;
string	   g_ProxyPort = "";
string     g_ProxyServer = "";
string	   g_ProxyAuthen = "";
string	   g_ProxyUser = "";
string	   g_ProxyPass = "";
int		   fCurrPictureRsrcID;
bool	   g_CanCheckIn = FALSE;
string	   g_AvailableStory = "yes";
int32	   HandleSelectedStatusFrame = kNoStatus;
/********************************************************************************************************************
 *****Function: CreateWorkspaceDir
 *****Creator:  Toan Nguyen
 *****IN: 
 *****out: 
 *****Objective: init workspace directory
 ********************************************************************************************************************/
int AMPUtils::CreateWorkspaceDir() {
	FSRef ref;
	OSType folderType = kCurrentUserFolderType;
	
	char pathSave[400];
	FSFindFolder( kUserDomain, folderType, kCreateFolder, &ref);
	FSRefMakePath(&ref, (uint8*)&pathSave, 400);
	//cout << "get Path: " << pathSave << endl;
	
	string tmpPath(pathSave);	//Users/currentUserLogin
	string excutePath("mkdir ");
	tmpPath += "/";
	tmpPath += WORKSPACE_DIR; //Users/currentUserLogin/AMPInDesignPlugin/
	excutePath += tmpPath;     
	system(excutePath.c_str()); //mkdir path
	g_System_WorkspaceDir = tmpPath;

	// create g_SDK_WorkspaceDir by get volume name and replace "/" by ":"
	char *volname = NULL;
	AMPUtils::volumeNameForPath(tmpPath.c_str(), &volname);
	//printf("volname: %s\n", volname);
	
	g_SDK_WorkspaceDir.assign(volname); // volume name 
	while (tmpPath.find("/") != string::npos) {
		tmpPath.replace(tmpPath.find("/"), 1, ":"); // replace "/" by ":"
	}
	
	g_SDK_WorkspaceDir += tmpPath; // example: Macintosh HD:Users:vutiet:AMPInDesignPlugin
	
	//cout << "g_WorkspaceDir " << g_WorkspaceDir << endl;
	DisposePtr(volname);
	
	//Create local directory to store log file
	string logPath(pathSave);	//Users/currentUserLogin
	string logDirectory = "mkdir " + logPath + "/" + ".adobe";
	system(logDirectory.c_str()); //mkdir path
	
	g_System_logDirectory = logPath + "/" + ".adobe";
	g_pageNumberCheckOut = "";
	g_pageEditing = "";
	g_issueEditing = "";
	g_pageCheckIn = "";
	fCurrPictureRsrcID = kAMPluginFirstPictureRsrcID;
	
	//g_Issueid = "";
	// Hidden folder
	excutePath = "chflags hidden " + g_System_WorkspaceDir;
	system(excutePath.c_str());
	InitLogCenter();
	
	return 0;
}

/********************************************************************************************************************
 *****Function: volumeNameForPath
 *****Creator:  Vu Tiet
 *****IN: const char *path, char **volname
 *****out: 
 *****Objective: init workspace directory
 ********************************************************************************************************************/
void AMPUtils::volumeNameForPath(const char *path, char **volname)
{//CFURLRef CFURLCreateWithString(CFAllocatorRef allocator, CFStringRef URLString, CFURLRef baseURL);
 //CFURLRef CFURLCreateWithFileSystemPath(CFAllocatorRef allocator, CFStringRef filePath, CFURLPathStyle pathStyle, Boolean isDirectory);
	CFStringRef pathRef = CFStringCreateWithCString(NULL, path, CFStringGetSystemEncoding());
	CFURLRef url = CFURLCreateWithString(NULL, pathRef, NULL);//CFURLCreateWithFileSystemPath
	FSRef bundleRef;
	FSCatalogInfo info;
	HFSUniStr255 volName;
	
	if (url)
	{
		if (CFURLGetFSRef(url, &bundleRef))
		{
			if (FSGetCatalogInfo(&bundleRef, kFSCatInfoVolume, &info, NULL, NULL, NULL) == noErr)
			{
				if ( FSGetVolumeInfo ( info.volume, 0, NULL, kFSVolInfoNone, NULL, &volName, NULL) == noErr)
				{
					CFStringRef stringRef = FSCreateStringFromHFSUniStr(NULL, &volName);
					if (stringRef)
					{
						*volname = NewPtr(CFStringGetLength(stringRef)+1);
						CFStringGetCString(stringRef, *volname, CFStringGetLength(stringRef)+1, kCFStringEncodingMacRoman);
						CFRelease(stringRef);
					}
				}
			}
		}
		
		CFRelease(url);
	}
}

/********************************************************************************************************************
 *****Function: RefreshMainPanel
 *****Creator:  Vu Tiet
 *****IN: int32 m_nPanelContrl
 *****out: 
 *****Objective: refresh panel
 ********************************************************************************************************************/	
void AMPUtils::RefreshMainPanel(int32 m_nPanelContrl) {
	// refresh listbox
	do
	{
		if(Utils<IPalettePanelUtils>() == nil) {
			break;
		}
		InterfacePtr<IPanelControlData> 
		panelData(Utils<IPalettePanelUtils>()->QueryPanelByWidgetID(kAMPluginPanelWidgetID));	
		// Don't assert, fail silently, the tree view panel may be closed.
		if(panelData == nil)
		{
			//cout << "panelData is nil" << endl;
			break;
		}

		IControlView* treeWidget = panelData->FindWidget(kAMPluginListBoxWidgetID);
		ASSERT(treeWidget);
		if(treeWidget == nil)
		{
			//cout << "treeWidget is nil" << endl;
			break;
		}
	
		// create new data list
		InterfacePtr<ITreeViewHierarchyAdapter> model(treeWidget, UseDefaultIID());
		ASSERT(model);
		if(!model) {
			break;
		}
		string HelloUser = "Sign out (" + g_Username + ")" ;

		K2Vector<PMString> lists;
		if (g_IsLoggedIn == TRUE) {
			//PMString signOutStr(kAMPItemBaseKey);
			//signOutStr.AppendNumber(3); // Sign out
			PMString signOutStr(HelloUser.c_str()); 
			signOutStr.Translate();
			lists.push_back(signOutStr);
		}
		else {
			PMString signInStr(kAMPItemBaseKey);
			signInStr.AppendNumber(1); // Sign in
			signInStr.Translate();
			lists.push_back(signInStr);
		}

		PMString browseIssueNodeName(kAMPItemBaseKey);
		browseIssueNodeName.AppendNumber(2); // Browse Issues
		browseIssueNodeName.Translate();
		lists.push_back(browseIssueNodeName);

		// create check in list
		//cout << "RefreshMainPanel: m_nPanelContrl - g_IsLoggedIn - g_DocName " << m_nPanelContrl << " - " << g_IsLoggedIn << " - " << g_DocName << endl;
		/////////////////////////
		// Vu Tiet
		// rem this line for testing check in without g_DocName
		//if(m_nPanelContrl == kAMPLuginCheckoutActionID && g_IsLoggedIn == TRUE && g_DocName.length() > 0)
		/////////////////////////
		if(m_nPanelContrl == kAMPLuginCheckoutActionID && g_IsLoggedIn == TRUE)
		{
			//cout << "++++++++++ RefreshMainPanel g_DocName: " << g_DocName << endl;
			// check in idml file
			if (g_DocName.length() > 0) {
				PMString checkInStr(kAMPItemBaseKey);
				checkInStr.AppendNumber(4); // check in
				checkInStr.Translate();
				lists.push_back(checkInStr);
			}

			// check lock of selected story
			for (int i = 0; i < g_TextFrameCount; i++) {
				if (g_SelectedTextFrameUID.compare(g_TextFrames[i].textframeUID) == 0) {
					//cout << "check lock of selected story / g_SelectedTextFrameUID - g_TextFrames[i].textframeUID " << g_SelectedTextFrameUID << " - " << g_TextFrames[i].textframeUID << endl;
					if (g_TextFrames[i].isLocked == TRUE) {
						// check in story
						//cout << "check in story" << endl;
						PMString checkInStoryStr(kAMPItemBaseKey);
						checkInStoryStr.AppendNumber(5); // check in story
						checkInStoryStr.Translate();
						lists.push_back(checkInStoryStr);						
					}
					else {
						// check out story
						//cout << "check out story" << endl;
						PMString checkOutStoryStr(kAMPItemBaseKey);
						checkOutStoryStr.AppendNumber(6); // check out story
						checkOutStoryStr.Translate();
						lists.push_back(checkOutStoryStr);						
					}
					break;
				}
			}
			
		}
		
		InterfacePtr<IStringListData> iListData(model, IID_ISTRINGLISTDATA);
		iListData->SetStringList(lists);
		
		// redraw UI
		InterfacePtr<ITreeViewMgr> treeMgr(treeWidget, UseDefaultIID());
		
		treeMgr->ClearTree();
		treeMgr->ChangeRoot(kTrue);
		
	}while(false);
}

void AMPUtils::CallJSDialog() {
	do 
	{
		/*
		 // put code script here
		 WideString scriptPath("D:\\AdobeSDK\\Adobe InDesign CS5.5 SDK\\build\\win\\release\\SDK\\SimpleDialog.jsx");
		 // Get a handle on the ExtendScript Manager
		 IDFile scriptFile(scriptPath);
		 //InterfacePtr<IScriptManager> scriptManager(Utils<IScriptUtils>()->QueryScriptManager(kJavaScriptMgrBoss));
		 //ASSERT(scriptManager);
		 //if (!scriptManager)
		 //	break;
		 
		 InterfacePtr<IScriptRunner>scriptRunner(Utils<IScriptUtils>()->QueryScriptRunner(scriptFile));
		 ASSERT(scriptRunner);
		 if (!scriptRunner)
		 break;
		 
		 RunScriptParams params(scriptRunner);
		 params.SetInvokeDebugger(kFalse);
		 params.SetShowErrorAlert(kTrue);
		 scriptRunner->RunScript(scriptPath, params);
		 */
		string strPath = g_System_WorkspaceDir + "/SimpleDialog.jsx";
		cout << "strPath: " << strPath << endl;
		WideString scriptPath(strPath.c_str());
		IDFile scriptFile(scriptPath);
		// assume scriptFile is an IDFile representing the script file to run
		InterfacePtr<IScriptRunner>scriptRunner(Utils<IScriptUtils>()->QueryScriptRunner(scriptFile));
		if (scriptRunner)
		{
			//ScriptRecordData arguments;
			//ScriptData resultData;
			//PMString errorString;
			//const bool16 showErrorAlert = kTrue;
			//const bool16 invokeDebugger = kFalse;
			//Utils<IScriptArgs>()->Save();
			//Utils<IScriptArgs>()->Set("paramkeyname1",scriptPath);
			//Utils<IScriptUtils>()->DispatchScriptRunner(scriptRunner,script,argum ents,resultData,errorString,kFalse);
			
			RunScriptParams params(scriptRunner);
			params.SetInvokeDebugger(kFalse);
			params.SetShowErrorAlert(kTrue);
			scriptRunner->RunFile(scriptFile, params);
		}
		
	} while (false);
}

/********************************************************************************************************************
 *****Function: RefreshMainPanelv
 *****Creator:  Toan Nguyen
 *****IN: const string &urlStr
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
string AMPUtils::getNameFromURL(const string &urlStr)
{
	string retString("");
	string tmpChar = "/";
	int xx, yy, zz = 0;
	for (xx = 0; xx < urlStr.length(); xx++)
	{
		if (urlStr[xx] == tmpChar[0])
			for(yy = xx; yy < urlStr.length(); yy++)
			{
				if (urlStr[yy] == tmpChar[0])
				{
					xx = yy;
					zz = xx + 1;
				}
				else if (yy == urlStr.length() - 1)
				{
					
					//cout << "last character :" << zz << endl;
					break;
				}
			}
	}
	for (xx = zz; xx < urlStr.length(); xx++)
	{
		retString += urlStr[xx];
	}
	return retString;
}

/********************************************************************************************************************
 *****Function: getid
 *****Creator:  Toan Nguyen
 *****IN: const string &urlStr
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::getid(const string &urlStr)
{
	string retString("");
	string tmpChar = "/";
	int xx;
	int16 count = 0;
	for (xx = 0; xx < urlStr.length(); xx++)
	{
		if (urlStr[xx] == tmpChar[0] && count == 0)
		{
			g_Magazineid = retString;
			retString = "";
			count++;
			continue;
		}
		else if (urlStr[xx] == tmpChar[0] && count == 1)
		{
			g_Issueid = retString;
			retString = "";
			count++;
			continue;
		}
		else if (urlStr[xx] == tmpChar[0] && count == 2)
		{
			g_Pageid= retString;
			retString = "";
			count++;
			continue;
		}
		else if(xx == (urlStr.length()-1))
		{
			retString += urlStr[xx];
			g_Storyid = retString;
			retString = "";
			break;
		}
		retString += urlStr[xx];
	}
#if _INDESIG_DEBUG
	cout << "urlStr " << urlStr << endl;
	cout << "g_Magazineid " << g_Magazineid << endl;
	cout << "g_Issueid " << g_Issueid << endl;
	cout << "g_Pageid " << g_Pageid << endl;
	cout << "g_Storyid " << g_Storyid << endl;
#endif
}

/*
void AMPUtils::GetStoryIDFromTextFrame() {
	do {
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			//cout << "docFrom == NULL" << endl;
			break;
		}
		UIDRef  docRef = GetUIDRef(docFrom); 
		AMPUtils::GetStoryIDFromTextFrame(docRef);
	} while (kFalse);
}
*/

/*
void AMPUtils::GetStoryIDFromTextFrame(UIDRef docRef) {
	do {
		
		//IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		//if (docFrom == NULL ) {
		//	cout << "docFrom == NULL" << endl;
		//	break;
		//}
		
		//UIDRef  docRef = GetUIDRef(docFrom); 
		InterfacePtr<IDocument> iDocument (docRef, IID_IDOCUMENT); 
		if(iDocument == nil) {
			//cout << "iDocument == nil" << endl;
			break; 
		}
		
		PMString docName; 
		iDocument->GetName(docName);
		//cout << "GetStoryIDFromTextFrame docName " << docName.GrabCString() << endl;
		
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			//cout << "storyList == nil" << endl;
			break;
		}
		
		// Iterate over all the stories
		if (g_TextFrames != NULL) {
			delete [] g_TextFrames;
		}
		g_TextFrameCount = 0;
		g_TextFrames = new textframes_t[storyList->GetAllTextModelCount()];
		//cout << "GetStoryIDFromTextFrame iterate over all the stories: " << storyList->GetAllTextModelCount() << endl;
		for (int32 i = 0; i < storyList->GetAllTextModelCount(); i++ )
		{
			TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(i);
			
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			int32 totalLength = textModel->TotalLength();
			//int32 primaryStoryThreadSpan = textModel->GetPrimaryStoryThreadSpan();
			
			TextIterator begin(textModel, 0);
			TextIterator end(textModel, totalLength-1);
			PMString str("");
			
			int32 beginStoryIDPos = -1;
			int32 endStoryIDPos = -1;
			
			for (TextIterator iter = begin; iter != end; iter++)
			{
				const UTF32TextChar characterCode = *iter;
				if (characterCode.GetValue() == 91) // "["
				{
					beginStoryIDPos = iter.Position();
					continue;
				}
				if (characterCode.GetValue() == 93) // "]" 
				{
					endStoryIDPos = iter.Position();
					break;
				}
				
				if (beginStoryIDPos > -1 && endStoryIDPos == -1) {
					//cout << "characterCode: " << characterCode.GetValue() << " ";
					PMString character;
					character.AppendW(characterCode);
					TextIndex position = iter.Position();
					str.Append(character.GrabCString());               
					//if (strlen(character.GrabCString()) > 2)
					//  str.Append(" ");
					//else
					//  str.Append(character.GrabCString());               
				}
				
			}
			
			string iStoryID = str.GrabCString();
			//cout << "GetStoryIDFromTextFrame iStoryID: " << iStoryID << endl;
			if (iStoryID.length() > 0) {
				// get component name then add to global array
				InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
				WideString nameStr;
				compName->Get(nameStr);
				string tmp;
				StringUtils::ConvertWideStringToUTF8(nameStr, tmp);
				//tmp += "/" + iStoryID;
				//g_TextFramesID[i] = tmp;
				//g_TextFrameCount++;
				g_TextFrames[g_TextFrameCount].textframeUID = tmp;
				g_TextFrames[g_TextFrameCount].storyID = iStoryID;
				g_TextFrames[g_TextFrameCount].isLocked = FALSE;
				//cout << "g_TextFrames[g_TextFrameCount].textframeUID: " << g_TextFrames[g_TextFrameCount].textframeUID << endl;
				g_TextFrameCount++;
				//cout << "g_TextFrameCount: " << g_TextFrameCount << endl;
			}
			
			
			//cout << "iStoryID " << i << " " << iStoryID << endl; 
			
			// remove story ID from text model
			SnpTextModelHelper	textCmdHelper;
			textCmdHelper.DeleteText(textModel, beginStoryIDPos, (endStoryIDPos-beginStoryIDPos+1));
						
		} // iterate stories
		
		
		
		// validate package info and set the current document
		//if (g_Package_id.length() < 1) {
		//	break;
		//}
		
		//g_DocName = docName.GrabCString();
		 
		
	}while (kFalse);
}
*/
#if 1
/********************************************************************************************************************
 *****Function: GetIDFromTextFrame
 *****Creator:  Vu Tiet
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::GetIDFromTextFrame() {
	do {
		if(Utils<ILayoutUIUtils>() == nil)
		{
			break;
		}
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			cout << "docFrom == NULL" << endl;
			break;
		}
		UIDRef  docRef = GetUIDRef(docFrom); 
		AMPUtils::GetIDFromTextFrame(docRef);
	} while (kFalse);
}

/********************************************************************************************************************
 *****Function: GetIDFromTextFrame
 *****Creator:  Vu Tiet
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::GetIDFromTextFrame(UIDRef docRef) {
	do {
		/*
		 IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		 if (docFrom == NULL ) {
		 cout << "docFrom == NULL" << endl;
		 break;
		 }*/
		AMPManipulateTextFrame instance;
		IDocument *iDocument;
		if (docRef != UIDRef::gNull) {
			InterfacePtr<IDocument> _docFrom (docRef, IID_IDOCUMENT); 
			if(_docFrom == nil) {
				cout << "_docFrom == nil" << endl;
				break; 
			}
			iDocument = _docFrom;
		}else {
			IDocument *_docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
			if (_docFrom == NULL ) {
				cout << "docFrom == NULL" << endl;
				break;
			}
			iDocument = _docFrom;
		}
		bool textframeDetect = FALSE;
		
		g_CanCheckIn = FALSE;
		if(g_AvailableStory == "no" && g_Package_id != "") { // page haven't any story
			iDocument->SetName(PMString(g_Package_id.c_str()));
			g_DocName = g_Package_id;
			g_CanCheckIn = TRUE;
			g_AvailableStory = "yes";
			//break;
		}else if(g_Package_id == ""){	//open from local machine
			string contentInfo;
			UIDRef storyInfo = AMPUtils::GetIDTextFrameInfo(iDocument, contentInfo);
			//AMPUtils::GetStoryInfoContent(storyInfo);
			string tempInfo = "Plugin_info::AudienceMediaInDesignPluginInformation::Plugin_info";
			if((storyInfo != UIDRef::gNull)&&(contentInfo != tempInfo)) {
				contentInfo = contentInfo.substr(tempInfo.length(), contentInfo.length());
				JSONHelper::AMPluginGetInfoMap(contentInfo);
				AMPUtils::QueryFrameRef(iDocument);
				//AMPUtils::AddToAssignment();
			}
		 	textframeDetect = (storyInfo == UIDRef::gNull) ? FALSE : TRUE;
			iDocument->SetName(PMString(g_Package_id.c_str()));	///
			break;///
		}
		
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			//cout << "storyList == nil" << endl;
			break;
		}
		int textModelCount = storyList->GetAllTextModelCount();
		int beginRemoves[textModelCount];
		int endRemoves[textModelCount];
		
		textframes_t newTextFrames[storyList->GetAllTextModelCount()];
		int newTextFrameCount = 0;
		//cout << "GetStoryIDFromTextFrame iterate over all the stories: " << storyList->GetAllTextModelCount() << endl;
		//for (int32 i = 0; i < storyList->GetAllTextModelCount(); i++ )
		for (int32 i = 0; i < textModelCount; i++ )
		{
			cout << "------story: " << i << endl;
			TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(i);
			
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			int32 totalLength = textModel->TotalLength();
			//int32 primaryStoryThreadSpan = textModel->GetPrimaryStoryThreadSpan();

			TextIterator begin(textModel, 0);
			TextIterator end(textModel, totalLength-1);
			PMString str("");
			
			int32 beginRemovedPos = -1;
			int32 endRemovedPos = -1;
			
			int32 beginRemovedSelf = -1;
			int32 endRemovedSelf = -1;
			
			for (TextIterator iter = begin; iter != end; iter++)
			{ 
				// get all content of textmodel
				const UTF32TextChar characterCode = *iter;
				PMString character;
				character.AppendW(characterCode);
				TextIndex position = iter.Position();
				str.Append(character.GrabCString());               
			}
			
			string iContent = str.GrabCString();
			
			// Find all [[[/idml_name]]]
			bool   id_Correct = FALSE;
			size_t count_header = 0;
			size_t iLenTagName = 0;
			size_t iEndTagName = -1;
			string itemp = iContent;
			string iTagNameStr;
			do {
				//cout << "find all idml_name tag:"<< count_header << " - package_id:" << g_Package_id << endl;
				iLenTagName = itemp.find("[[[/idml_name]]]");
				if(iLenTagName != string::npos) {
					iTagNameStr = itemp.substr(15, iLenTagName-15);
					itemp = itemp.erase(0,iLenTagName+16);
					count_header++;
					iEndTagName = iEndTagName + iLenTagName+16-1;
					//cout << "iTagNameStr:" << iTagNameStr << endl;
					if (g_Package_id.compare(iTagNameStr) == 0) {
						cout << "header is correct" << endl;
						iDocument->SetName(PMString(g_Package_id.c_str()));
						g_DocName = g_Package_id;
						g_CanCheckIn = TRUE;
						id_Correct = TRUE;
					}
				}
			}while(iLenTagName != string::npos);
			
			if (id_Correct==TRUE) {										// check out pages
				beginRemovedPos = 0;
				endRemovedPos = iEndTagName;
			} else if(g_Package_id.compare(g_DocName) == 0) {			// open normal
				//cout << "this used to open idml if it haven't header" << endl;
				iDocument->SetName(PMString(g_Package_id.c_str()));
				beginRemovedPos = 0;
				endRemovedPos = iEndTagName;
			} else if (textframeDetect==TRUE){
				//cout << "this used to restore path" << endl;// Restore path
				iDocument->SetName(PMString(g_Package_id.c_str()));
				return;
			}
			//cout << "---beginPackagePos - endPackagePos: " << beginRemovedPos << " - " << endRemovedPos << endl;
			//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			size_t beginStorySelf = iContent.find("[[[story_self]]]");
			size_t endStorySelf = iContent.find("[[[/story_self]]]");
			//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			size_t beginStoryAttribute = iContent.find("[[[story_attribute]]]");
			size_t endStoryAttribute = iContent.find("[[[/story_attribute]]]");
			//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			size_t beginStoryPos = iContent.find("[[[story_id]]]");
			size_t endStoryPos = iContent.find("[[[/story_id]]]");
			//cout << "beginStoryPos - endStoryPos: " << beginStoryPos << " - " << endStoryPos << endl;
			//cout << "beginRemovedPos - endRemovedPost: " << beginRemovedPos << " - " << endRemovedPos << endl;
			if (beginStoryPos != string::npos && endStoryPos != string::npos) {
				if ((beginStoryPos < beginRemovedPos) || beginRemovedPos == -1) {
					beginRemovedPos = beginStoryPos;
				}
				if ((endStoryPos > endRemovedPos) || endRemovedPos == -1) {
					endRemovedPos = endStoryPos+15-1; // length of [[[/story_id]]] is 15
				}
				if ((beginStorySelf < beginRemovedPos) || beginRemovedPos == -1) {
					beginRemovedPos = beginStorySelf;
				}
				if ((endStorySelf > endRemovedPos) || endRemovedPos == -1) {
					endRemovedPos = endStorySelf+17-1; // length of [[[/story_seft]]] is 17
				}
				//++++++++++++++++++++++++++++++++++++++++++++
				if ((beginStoryAttribute != string::npos) && (beginStoryAttribute < beginRemovedPos || beginRemovedPos == -1)) {
					beginRemovedPos = beginStoryAttribute;
				}
				if ((endStoryAttribute != string::npos) && (endStoryAttribute > endRemovedSelf || endRemovedSelf == -1)) {
					endRemovedPos = endStoryAttribute+22-1; // length of [[[/story_attribute]]] is 17
				}
				//cout << "xxbeginRemovedPos - endRemovedPost: " << beginRemovedPos << " - " << endRemovedPos << endl;
				//++++++++++++++++++++++++++++++++++++++++++++
				string iStoryID = iContent.substr(beginStoryPos+14, endStoryPos-beginStoryPos-14); // length of [[[story_id]]] is 14
				string iStorySelf = iContent.substr(beginStorySelf+16, endStorySelf-beginStorySelf-16); // length of [[[story_self]]] is 16 [[[/story_self]]] is 16
				string iAttribute = iContent.substr(beginStoryAttribute+21, endStoryAttribute-beginStoryAttribute-21); // length of [[[story_attribute]]] is 21 [[[/story_attribute]]] is 22
				//cout << "Get iContent: " << iContent << endl;
				//cout << "Get iStorySelf: " << iStorySelf << endl;
				
				if (iStoryID.length() > 0) {
					// get component name then add to global array
					InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
					WideString nameStr;
					compName->Get(nameStr);
					string tmp;
					StringUtils::ConvertWideStringToUTF8(nameStr, tmp);
					//g_TextFrames[g_TextFrameCount].textframeUID = tmp;
					//g_TextFrames[g_TextFrameCount].storyID = iStoryID;
					newTextFrames[newTextFrameCount].textframeUID = tmp;
					newTextFrames[newTextFrameCount].storyID = iStoryID;
					newTextFrames[newTextFrameCount].beginRemovePos = beginRemovedPos;
					newTextFrames[newTextFrameCount].endRemovePos = endRemovedPos;
					newTextFrames[newTextFrameCount].isLocked = FALSE;
					newTextFrames[newTextFrameCount].storySelf = iStorySelf;
					newTextFrames[newTextFrameCount].attribute = iAttribute;
					//newTextFrames[newTextFrameCount].beginRemoveSelf = beginRemovedSelf;
					//newTextFrames[newTextFrameCount].endRemoveSelf = endRemovedSelf;
					//UIDRef pageItemRef = instance.QueryGraphicFrameRef(storyUIDRef);
					pt_assignStr addedStoryass;
					addedStoryass.story_assignment = storyUIDRef;
					addedStoryass.frameUIDRef = instance.QueryGraphicFrameRef(storyUIDRef);
					addedStoryass.story_id = iStoryID;
					addedStoryass._status = GRAPHICFRAME_AVAILABLE;
					addedStoryass.storyUID = tmp;
					g_assignmentPtr.push_back(addedStoryass);
					
					for (int j = 0; j < g_TextFrameCount; j++) {
						if (iStoryID.compare(g_TextFrames[j].storyID) == 0) {
							//g_TextFrames[g_TextFrameCount].isLocked = temp_TextFrames[j].isLocked;
							//g_TextFrames[g_TextFrameCount].sessionID = temp_TextFrames[j].sessionID;
							newTextFrames[newTextFrameCount].isLocked = g_TextFrames[j].isLocked;
							newTextFrames[newTextFrameCount].sessionID = g_TextFrames[j].sessionID;
							newTextFrames[newTextFrameCount].storyName = g_TextFrames[j].storyName;
							//cout << "g_TextFrames[j].storyName: " << g_TextFrames[j].storyName << endl;
							break;
						}
					}
					
					//cout << "g_TextFrames[g_TextFrameCount].textframeUID: " << g_TextFrames[g_TextFrameCount].textframeUID << endl;
					//g_TextFrameCount++;
					newTextFrameCount++;
					//cout << "g_TextFrameCount: " << g_TextFrameCount << endl;
					//cout << "GetStoryIDFromTextFrame iStoryID: " << iStoryID << endl;
					//cout << "beginRemovedPos - endRemovedPos: " << beginRemovedPos << " - " << endRemovedPos << endl;
				}
			}
			
			// remove story ID and package ID from text model
			//SnpTextModelHelper	textCmdHelper;
			//textCmdHelper.DeleteText(textModel, beginRemovedPos, (endRemovedPos-beginRemovedPos+1));
			beginRemoves[i] = beginRemovedPos;
			endRemoves[i] = (endRemovedPos-beginRemovedPos+1);
			
			//cout << "end loop story: " << i << endl;
			
		} // iterate stories
		
		//delete [] temp_TextFrames;
		
		if (g_CanCheckIn == FALSE) {
			cout << "this document is invalid or this funcion was called by wrong signal. QUIT NOW" << endl;
			return;
		}
		
		// get selected issue
		Issue selectedIssue;
		bool hasSelectedIssue = FALSE;
		//if (g_Magazineid.length() > 0 and g_Issueid.length() > 0) {
		if (g_Issueid.length() > 0) {
			//cout << "g_Magazine_Count: " << g_Magazine_Count << endl;
			for (int ii = 0; ii < g_Magazine_Count; ii++) {
				//if (g_Magazines[ii]._id.compare(g_Magazineid) == 0) {
				for (int jj = 0; jj < g_Magazines[ii]._issueSize; jj++) {
					//cout << "jj issue - g_issueid: " << g_Magazines[ii]._issues[jj]._id << " - " << g_Issueid << endl;
					if (g_Magazines[ii]._issues[jj]._id.compare(g_Issueid) == 0) {
						selectedIssue = g_Magazines[ii]._issues[jj];
						hasSelectedIssue = TRUE;
						break;
					}
				}
				//}
			}
		}	
		//cout << "selectedIssue: " << selectedIssue._name << endl;
		
		// write to g_TextFrames
		//cout << "write to g_TextFrames:" << endl;
		if (g_TextFrames != NULL) {
			delete [] g_TextFrames;
		}
		//cout << "write to g_TextFrames2:" << g_TextFrameCount << endl;
		g_TextFrameCount = newTextFrameCount;
		g_TextFrames = new textframes_t[g_TextFrameCount];
		
		for (int k = 0; k < g_TextFrameCount; k++) {
			g_TextFrames[k].textframeUID = newTextFrames[k].textframeUID;
			g_TextFrames[k].storyID = newTextFrames[k].storyID;
			g_TextFrames[k].isLocked = newTextFrames[k].isLocked;
			g_TextFrames[k].sessionID = newTextFrames[k].sessionID;
			g_TextFrames[k].storyName = newTextFrames[k].storyName;
			g_TextFrames[k].beginRemovePos = newTextFrames[k].beginRemovePos;
			g_TextFrames[k].endRemovePos = newTextFrames[k].endRemovePos;
			g_TextFrames[k].storySelf = newTextFrames[k].storySelf;
			g_TextFrames[k].attribute = newTextFrames[k].attribute;
			//g_TextFrames[k].beginRemoveSelf = newTextFrames[k].beginRemoveSelf;
			//g_TextFrames[k].endRemoveSelf = newTextFrames[k].endRemoveSelf;
			//cout << "g_Magazineid - g_Issueis: " << g_Magazineid << " - " << g_Issueid << endl; 
			//cout << "endRemovedSelf: " << g_TextFrames[k].textframeUID << " - " << g_TextFrames[k].storyID << g_TextFrames[k].isLocked << " - story_self: " << g_TextFrames[k].storySelf << endl;
			//if (g_Magazineid.length() > 0 and g_Issueid.length() > 0) {
			if (g_Issueid.length() > 0 && hasSelectedIssue == TRUE) {
				for (int kk = 0; kk < selectedIssue._pageSize; kk++) {
					for (int mm = 0; mm < selectedIssue._pages[kk]._storySize; mm++) {
						if (selectedIssue._pages[kk]._stories[mm]._id.compare(g_TextFrames[k].storyID) == 0) {
							g_TextFrames[k].storyName = selectedIssue._pages[kk]._stories[mm]._name;
							cout << "---------- storyName: " << g_TextFrames[k].storyName << endl;
							break;
						}
					} 
				}
			}
		}
		
		for (int32 ii = 0; ii < textModelCount; ii++ ) {
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(ii);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			
			// remove story ID and package ID from text model
			SnpTextModelHelper	textCmdHelper;
			textCmdHelper.DeleteText(textModel, beginRemoves[ii], endRemoves[ii]);
		}
		
		if (g_TextFrameCount > 0 && g_ImageInfo.size() > 0) {
			g_ImageInfo.clear();
		}
		
		cout << "end function GetIDFromTextFrame" << endl;
		
	} while (kFalse);
}

#else
/********************************************************************************************************************
 *****Function: GetIDFromTextFrame
 *****Creator:  Vu Tiet
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::GetIDFromTextFrame() {
	do {
		if(Utils<ILayoutUIUtils>() == nil)
		{
			break;
		}
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			cout << "docFrom == NULL" << endl;
			break;
		}
		UIDRef  docRef = GetUIDRef(docFrom); 
		AMPUtils::GetIDFromTextFrame(docRef);
	} while (kFalse);
}
/********************************************************************************************************************
 *****Function: GetIDFromTextFrame
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::GetIDFromTextFrame(UIDRef docRef) {
	do {
		/*
		 IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		 if (docFrom == NULL ) {
		 cout << "docFrom == NULL" << endl;
		 break;
		 }*/
		
		//UIDRef  docRef = GetUIDRef(docFrom); 
		InterfacePtr<IDocument> iDocument (docRef, IID_IDOCUMENT); 
		if(iDocument == nil) {
			cout << "iDocument == nil" << endl;
			break; 
		}
		
		g_CanCheckIn = FALSE;
		if(g_AvailableStory == "no") { // page haven't any story
			iDocument->SetName(PMString(g_Package_id.c_str()));
			g_DocName = g_Package_id;
			g_CanCheckIn = TRUE;
			g_AvailableStory = "yes";
			//break;
		}
		//PMString docName; 
		//iDocument->GetName(docName);
		//cout << "GetStoryIDFromTextFrame docName " << docName.GrabCString() << endl;
		//iDocument->SetName(PMString("Vuta"));
		
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			//cout << "storyList == nil" << endl;
			break;
		}
		
		// Iterate over all the stories
		//textframes_t temp_TextFrames[g_TextFrameCount];
		//int temp_TextFrame_Count = g_TextFrameCount;
		/*
		if (g_TextFrames != NULL) {
			for (int i = 0; i < g_TextFrameCount; i++) {
				temp_TextFrames[i].textframeUID = g_TextFrames[i].textframeUID;
				temp_TextFrames[i].storyID = g_TextFrames[i].storyID;
				temp_TextFrames[i].sessionID = g_TextFrames[i].sessionID;
				temp_TextFrames[i].isLocked = g_TextFrames[i].isLocked;
			}
			delete [] g_TextFrames;
		}
		g_TextFrameCount = 0;
		g_TextFrames = new textframes_t[storyList->GetAllTextModelCount()];
		*/
		
		int textModelCount = storyList->GetAllTextModelCount();
		int beginRemoves[textModelCount];
		int endRemoves[textModelCount];
		
		textframes_t newTextFrames[storyList->GetAllTextModelCount()];
		int newTextFrameCount = 0;
		cout << "GetStoryIDFromTextFrame iterate over all the stories: " << storyList->GetAllTextModelCount() << endl;
		//for (int32 i = 0; i < storyList->GetAllTextModelCount(); i++ )
		for (int32 i = 0; i < textModelCount; i++ )
		{
			cout << "++++++story: " << i << endl;
			TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(i);
			
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			int32 totalLength = textModel->TotalLength();
			//int32 primaryStoryThreadSpan = textModel->GetPrimaryStoryThreadSpan();
			
			TextIterator begin(textModel, 0);
			TextIterator end(textModel, totalLength-1);
			PMString str("");
			
			int32 beginRemovedPos = -1;
			int32 endRemovedPos = -1;
			
			int32 beginRemovedSelf = -1;
			int32 endRemovedSelf = -1;
			
			for (TextIterator iter = begin; iter != end; iter++)
			{ 
				// get all content of textmodel
				const UTF32TextChar characterCode = *iter;
				PMString character;
				character.AppendW(characterCode);
				TextIndex position = iter.Position();
				str.Append(character.GrabCString());               
			}
			
			string iContent = str.GrabCString();
			
			// find textframe stores info 
			size_t start_info = iContent.find("Plugin_info::");
			size_t end_info = iContent.find("::Plugin_info");
			if (start_info != string::npos && end_info != string::npos) {
				//cout << "info of package is already exsited" << endl;
				//AMPUtils::GetStoryInfoContent();
				cout << "Get Story Info Content" << endl;
				// login to continue working
				//g_CanCheckIn = TRUE;
				continue;
			}
			
			//cout << "iContent: " << iContent << endl;
			size_t beginPackagePos = iContent.find("[[[idml_name]]]");
			size_t endPackagePos = iContent.find("[[[/idml_name]]]");
			cout << "beginPackagePos - endPackagePos: " << beginPackagePos << " - " << endPackagePos << endl;
			//cout << "beginRemovedPos - endRemovedPost: " << beginRemovedPos << " - " << endRemovedPos << endl;
			if (beginPackagePos != string::npos && endPackagePos != string::npos) {
				beginRemovedPos = beginPackagePos;
				endRemovedPos = endPackagePos+16-1; // length of [[[/idml_name]]] is 16
				//g_Package_id = iContent.substr(beginPackagePos+16, endPackagePos-beginPackagePos-16); // length of [[[idml_name]]] is 15 
				// assign doc name to g_DocName
				string temp = iContent.substr(beginPackagePos+15, endPackagePos-beginPackagePos-15);
				//cout << "g_Package_id - textFramePackageID " << g_Package_id << " - " << temp << endl;
				if (g_Package_id.compare(iContent.substr(beginPackagePos+15, endPackagePos-beginPackagePos-15)) == 0) { // length of [[[idml_name]]] is 15 
					iDocument->SetName(PMString(g_Package_id.c_str()));
					//g_DocName = docName.GrabCString();
					g_DocName = g_Package_id;
					g_CanCheckIn = TRUE;
				}
				else {
					// this is not checked out package, so quit
					cout << "this is not checked out package, so quit" << endl;
					return;
				}
			} else if(g_Package_id.compare(g_DocName) == 0) {
				cout << "this used to open idml if it haven't header" << endl;
				iDocument->SetName(PMString(g_Package_id.c_str()));
			}
			 
			//cout << "GetIDFromTextFrame g_Package_id - g_DocName: " << g_Package_id << " - " << g_DocName << endl;
			// Toan add here for test
			//cout << "[[[package_id]]]xxx[[[/package_id]]]" << endl;
			//iDocument->SetName(PMString(g_Package_id.c_str()));
			//g_DocName = g_Package_id;	// add to test here
			//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			size_t beginStorySelf = iContent.find("[[[story_self]]]");
			size_t endStorySelf = iContent.find("[[[/story_self]]]");
			//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			size_t beginStoryPos = iContent.find("[[[story_id]]]");
			size_t endStoryPos = iContent.find("[[[/story_id]]]");
			//cout << "beginStoryPos - endStoryPos: " << beginStoryPos << " - " << endStoryPos << endl;
			//cout << "beginRemovedPos - endRemovedPost: " << beginRemovedPos << " - " << endRemovedPos << endl;
			if (beginStoryPos != string::npos && endStoryPos != string::npos) {
				if (beginStoryPos < beginRemovedPos || beginRemovedPos == -1) {
					beginRemovedPos = beginStoryPos;
				}
				if (endStoryPos > endRemovedPos || endRemovedPos == -1) {
					endRemovedPos = endStoryPos+15-1; // length of [[[/story_id]]] is 15
				}
				if (beginStorySelf < beginRemovedPos || beginRemovedPos == -1) {
					beginRemovedPos = beginStorySelf;
				}
				if (endStorySelf > endRemovedSelf || endRemovedSelf == -1) {
					endRemovedPos = endStorySelf+17-1; // length of [[[/story_seft]]] is 17
				}
				string iStoryID = iContent.substr(beginStoryPos+14, endStoryPos-beginStoryPos-14); // length of [[[story_id]]] is 14
				string iStorySelf = iContent.substr(beginStorySelf+16, endStorySelf-beginStorySelf-16); // length of [[[story_self]]] is 16 [[[/story_self]]] is 16
				//cout << "Get iContent: " << iContent << endl;
				//cout << "Get iStorySelf: " << iStorySelf << endl;
				if (iStoryID.length() > 0) {
					// get component name then add to global array
					InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
					WideString nameStr;
					compName->Get(nameStr);
					string tmp;
					StringUtils::ConvertWideStringToUTF8(nameStr, tmp);
					//g_TextFrames[g_TextFrameCount].textframeUID = tmp;
					//g_TextFrames[g_TextFrameCount].storyID = iStoryID;
					newTextFrames[newTextFrameCount].textframeUID = tmp;
					newTextFrames[newTextFrameCount].storyID = iStoryID;
					newTextFrames[newTextFrameCount].beginRemovePos = beginRemovedPos;
					newTextFrames[newTextFrameCount].endRemovePos = endRemovedPos;
					newTextFrames[newTextFrameCount].isLocked = FALSE;
					newTextFrames[newTextFrameCount].storySelf = iStorySelf;
					//newTextFrames[newTextFrameCount].beginRemoveSelf = beginRemovedSelf;
					//newTextFrames[newTextFrameCount].endRemoveSelf = endRemovedSelf;
					
					for (int j = 0; j < g_TextFrameCount; j++) {
						if (iStoryID.compare(g_TextFrames[j].storyID) == 0) {
							//g_TextFrames[g_TextFrameCount].isLocked = temp_TextFrames[j].isLocked;
							//g_TextFrames[g_TextFrameCount].sessionID = temp_TextFrames[j].sessionID;
							newTextFrames[newTextFrameCount].isLocked = g_TextFrames[j].isLocked;
							newTextFrames[newTextFrameCount].sessionID = g_TextFrames[j].sessionID;
							newTextFrames[newTextFrameCount].storyName = g_TextFrames[j].storyName;
							//cout << "g_TextFrames[j].storyName: " << g_TextFrames[j].storyName << endl;
							break;
						}
					}
					
					//cout << "g_TextFrames[g_TextFrameCount].textframeUID: " << g_TextFrames[g_TextFrameCount].textframeUID << endl;
					//g_TextFrameCount++;
					newTextFrameCount++;
					//cout << "g_TextFrameCount: " << g_TextFrameCount << endl;
					//cout << "GetStoryIDFromTextFrame iStoryID: " << iStoryID << endl;
					//cout << "beginRemovedPos - endRemovedPos: " << beginRemovedPos << " - " << endRemovedPos << endl;
				}
			}
			
			// remove story ID and package ID from text model
			//SnpTextModelHelper	textCmdHelper;
			//textCmdHelper.DeleteText(textModel, beginRemovedPos, (endRemovedPos-beginRemovedPos+1));
			beginRemoves[i] = beginRemovedPos;
			endRemoves[i] = (endRemovedPos-beginRemovedPos+1);
			
			//cout << "end loop story: " << i << endl;
			
		} // iterate stories
		
		//delete [] temp_TextFrames;
		
		if (g_CanCheckIn == FALSE) {
			cout << "this document is invalid or this funcion was called by wrong signal. QUIT NOW" << endl;
			return;
		}
		
		// get selected issue
		Issue selectedIssue;
		bool hasSelectedIssue = FALSE;
		//if (g_Magazineid.length() > 0 and g_Issueid.length() > 0) {
		if (g_Issueid.length() > 0) {
			//cout << "g_Magazine_Count: " << g_Magazine_Count << endl;
			for (int ii = 0; ii < g_Magazine_Count; ii++) {
				//if (g_Magazines[ii]._id.compare(g_Magazineid) == 0) {
					for (int jj = 0; jj < g_Magazines[ii]._issueSize; jj++) {
						//cout << "jj issue - g_issueid: " << g_Magazines[ii]._issues[jj]._id << " - " << g_Issueid << endl;
						if (g_Magazines[ii]._issues[jj]._id.compare(g_Issueid) == 0) {
							selectedIssue = g_Magazines[ii]._issues[jj];
							hasSelectedIssue = TRUE;
							break;
						}
					}
				//}
			}
		}	
		cout << "selectedIssue: " << selectedIssue._name << endl;
		
		// write to g_TextFrames
		cout << "write to g_TextFrames:" << endl;
		if (g_TextFrames != NULL) {
			delete [] g_TextFrames;
		}
		cout << "write to g_TextFrames2:" << g_TextFrameCount << endl;
		g_TextFrameCount = newTextFrameCount;
		g_TextFrames = new textframes_t[g_TextFrameCount];
		
		for (int k = 0; k < g_TextFrameCount; k++) {
			g_TextFrames[k].textframeUID = newTextFrames[k].textframeUID;
			g_TextFrames[k].storyID = newTextFrames[k].storyID;
			g_TextFrames[k].isLocked = newTextFrames[k].isLocked;
			g_TextFrames[k].sessionID = newTextFrames[k].sessionID;
			g_TextFrames[k].storyName = newTextFrames[k].storyName;
			g_TextFrames[k].beginRemovePos = newTextFrames[k].beginRemovePos;
			g_TextFrames[k].endRemovePos = newTextFrames[k].endRemovePos;
			g_TextFrames[k].storySelf = newTextFrames[k].storySelf;
			//g_TextFrames[k].beginRemoveSelf = newTextFrames[k].beginRemoveSelf;
			//g_TextFrames[k].endRemoveSelf = newTextFrames[k].endRemoveSelf;
			//cout << "g_Magazineid - g_Issueis: " << g_Magazineid << " - " << g_Issueid << endl; 
			//cout << "endRemovedSelf: " << g_TextFrames[k].textframeUID << " - " << g_TextFrames[k].storyID << g_TextFrames[k].isLocked << " - story_self: " << g_TextFrames[k].storySelf << endl;
			//if (g_Magazineid.length() > 0 and g_Issueid.length() > 0) {
			if (g_Issueid.length() > 0 && hasSelectedIssue == TRUE) {
				for (int kk = 0; kk < selectedIssue._pageSize; kk++) {
					for (int mm = 0; mm < selectedIssue._pages[kk]._storySize; mm++) {
						if (selectedIssue._pages[kk]._stories[mm]._id.compare(g_TextFrames[k].storyID) == 0) {
							g_TextFrames[k].storyName = selectedIssue._pages[kk]._stories[mm]._name;
							cout << "---------- storyName: " << g_TextFrames[k].storyName << endl;
							break;
						}
					} 
				}
			}
		}
		
		for (int32 ii = 0; ii < textModelCount; ii++ ) {
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(ii);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}

			// remove story ID and package ID from text model
			SnpTextModelHelper	textCmdHelper;
			textCmdHelper.DeleteText(textModel, beginRemoves[ii], endRemoves[ii]);
		}
		
		if (g_TextFrameCount > 0 && g_ImageInfo.size() > 0) {
			g_ImageInfo.clear();
		}
		
		cout << "end function GetIDFromTextFrame" << endl;
		
	} while (kFalse);
}
#endif	// 20121130 <-- Toan

/*
bool AMPUtils::SetStoryIDToTextFrame() {
	bool res = FALSE;
	do {
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			//cout << "docFrom == NULL" << endl;
			break;
		}
		UIDRef  docRef = GetUIDRef(docFrom); 
		res = AMPUtils::SetStoryIDToTextFrame(docRef);
	} while (kFalse);
	return res;
}
 */

/*
bool AMPUtils::SetStoryIDToTextFrame(UIDRef docRef) {
	bool res = FALSE;
	do {

		//IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		//if (docFrom == NULL ) {
		//	cout << "docFrom == NULL" << endl;
		//	break;
		//}
		
		//UIDRef  docRef = GetUIDRef(docFrom); 

		InterfacePtr<IDocument> iDocument (docRef, IID_IDOCUMENT); 
		if(iDocument == nil) {
			//cout << "iDocument == nil" << endl;
			break; 
		}
		
		PMString docName; 
		iDocument->GetName(docName);
		//cout << "GetStoryIDFromTextFrame docName " << docName.GrabCString() << endl;
		
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			//cout << "storyList == nil" << endl;
			break;
		}
		
		// Iterate over all the stories
		for (int32 i = 0; i < storyList->GetAllTextModelCount(); i++ )
		{
			TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(i);
			
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			
			// get component name
			InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
			WideString nameWStr;
			compName->Get(nameWStr);
			string nameStr;
			StringUtils::ConvertWideStringToUTF8(nameWStr, nameStr);
			//cout << "g_TextFrameCount: " << g_TextFrameCount << endl;
			for (int j = 0; j < g_TextFrameCount; j++) {
				//cout << "g_TextFrames[j].textframeUID - nameStr: " << g_TextFrames[j].textframeUID << " - " << nameStr << endl;
				if (g_TextFrames[j].textframeUID.compare(nameStr) == 0) {
					string storyIDStr = "[" + g_TextFrames[j].storyID + "]";
					PMString storyIDPMStr(storyIDStr.c_str());
					WideString storyIDWStr(storyIDPMStr);
					boost::shared_ptr<WideString>	wide(new WideString(storyIDWStr));
					SnpTextModelHelper	textCmdHelper;
					textCmdHelper.InsertText(textModel, 0, wide);
					break;
				}
			}
		} // iterate stories
		
		res = TRUE;
	}while (kFalse);
	return res;
}
*/


/********************************************************************************************************************
 *****Function: SetIDToTextFrame
 *****Creator:  Vu Tiet
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::SetIDToTextFrame() {
	bool res = FALSE;
	do {
		if(Utils<ILayoutUIUtils>() == nil)
		{
			break;
		}
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			//cout << "docFrom == NULL" << endl;
			break;
		}
		UIDRef  docRef = GetUIDRef(docFrom); 
		res = AMPUtils::SetIDToTextFrame(docRef);
	} while (kFalse);
	return res;
}

bool AMPUtils::SetIDToTextFrame(UIDRef docRef) {
	bool res = FALSE;
	do {
		/*
		 IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		 if (docFrom == NULL ) {
		 cout << "docFrom == NULL" << endl;
		 break;
		 }
		 
		 UIDRef  docRef = GetUIDRef(docFrom);
		 */
		InterfacePtr<IDocument> iDocument (docRef, IID_IDOCUMENT); 
		if(iDocument == nil) {
			//cout << "iDocument == nil" << endl;
			break; 
		}
		
		PMString docName; 
		iDocument->GetName(docName);
		//cout << "GetStoryIDFromTextFrame docName " << docName.GrabCString() << endl;
		
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			//cout << "storyList == nil" << endl;
			break;
		}
		
		//bool addedPackageID = FALSE;
		// Iterate over all the stories
		for (int32 i = 0; i < storyList->GetAllTextModelCount(); i++ )
		{
			TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(i);
			
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			
			// find textframe stores info 
			string tmp;
			if(AMPUtils::GetIDTextFrameInfo(iDocument, tmp) == storyUIDRef)
				continue;
			
			// get component name
			InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
			WideString nameWStr;
			compName->Get(nameWStr);
			string nameStr;
			StringUtils::ConvertWideStringToUTF8(nameWStr, nameStr);
			//cout << "g_TextFrameCount: " << g_TextFrameCount << endl;
			for (int j = 0; j < g_TextFrameCount; j++) {
				//cout << "g_TextFrames[j].textframeUID - nameStr: " << g_TextFrames[j].textframeUID << " - " << nameStr << endl;
				if (g_TextFrames[j].textframeUID.compare(nameStr) == 0) {
					//string storyIDStr = "[[[story_id]]]" + g_TextFrames[j].storyID + "[[[/story_id]]]";
					string storyIDStr = "[[[story_id]]]" + g_TextFrames[j].storyID + "[[[/story_id]]]" + "[[[story_self]]]" + g_TextFrames[j].storySelf + "[[[/story_self]]]";// + \
										"[[[story_attribute]]]" + g_TextFrames[j].attribute + "[[[/story_attribute]]]";
					PMString storyIDPMStr(storyIDStr.c_str());
					WideString storyIDWStr(storyIDPMStr);
					boost::shared_ptr<WideString>	wide(new WideString(storyIDWStr));
					SnpTextModelHelper	textCmdHelper;
					textCmdHelper.InsertText(textModel, 0, wide);
					g_TextFrames[j].beginRemovePos = 0;
					g_TextFrames[j].endRemovePos = storyIDStr.length();
					
					/*
					// add package id
					if (addedPackageID == FALSE) {
						string packageID = "[[[idml_name]]]" + g_Package_id + "[[[/idml_name]]]";
						PMString packageIDPMStr(packageID.c_str());
						WideString packageIDWStr(packageIDPMStr);
						boost::shared_ptr<WideString>	wide1(new WideString(packageIDWStr));
						SnpTextModelHelper	textCmdHelper1;
						textCmdHelper1.InsertText(textModel, 0, wide1);
						addedPackageID = TRUE;
						g_TextFrames[j].endRemovePos = packageID.length() + g_TextFrames[j].endRemovePos;
					}
					*/
					
					break;
				}
			}
		} // iterate stories
		
		res = TRUE;
	}while (kFalse);
	return res;
}


/********************************************************************************************************************
 *****Function: PostStoryToCMS
 *****Creator:  Vu Tiet
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
extern UIDRef tempFrameCheckedIn;
void AMPUtils::PostStoryToCMS() {

	do {
		InterfacePtr<ISnipRunSuite> suite(Utils<ISelectionUtils>()->GetActiveSelection(), UseDefaultIID());
		if (!suite) {
			break;
		}
		
		ISnipRunSuite::SnippetName snippetName = PMString("CheckInStory");
		PMString parameters("");
		bool16 enableParameterDialog = kFalse;
		
		// Run the snippet.
		if (suite->CanRun(snippetName) == kFalse) {
			cout << "CanRun Failed" << endl;
		}
		else {
			ErrorCode status = suite->Run(snippetName, parameters, enableParameterDialog);						
			//cout << "--CheckInStory status:" << status << endl;
			//<--
			AMPUtils::SaveDocument();	//Toan added here
			if(status == kSuccess){
				AMPUtils::UpdateStatusProperties(tempFrameCheckedIn, GRAPHICFRAME_AVAILABLE);
				tempFrameCheckedIn = UIDRef::gNull;
			}
			//-->
		}
		
	} while(false);
	
}
/********************************************************************************************************************
 *****Function: ImportStoryFromCMS
 *****Creator:  Vu Tiet
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::ImportStoryFromCMS() {
	
	do {
		InterfacePtr<ISnipRunSuite> suite(Utils<ISelectionUtils>()->GetActiveSelection(), UseDefaultIID());
		if (!suite) {
			// If there's no ISnipRunSuite then no snippets can be run so disable the button.
			break;
		}
		
		ISnipRunSuite::SnippetName snippetName = PMString("CheckOutStory");
		PMString parameters("");
		bool16 enableParameterDialog = kFalse;
		
		// Run the snippet.
		if (suite->CanRun(snippetName) == kFalse) {
			cout << "CanRun Failed" << endl;
		}
		else {
			ErrorCode status = suite->Run(snippetName, parameters, enableParameterDialog);						
		}
	} while(false);
	
}
/********************************************************************************************************************
 *****Function: DoUseResponder
 *****Creator:  Vu Tiet
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::DoUseResponder()
{
	if (DocWchUtils::QueryDocResponderMode())
	{
		cout << "Stop doc responder mode" << endl;
		DocWchUtils::StopDocResponderMode();
	}
	else
	{
		cout << "start doc responder mode" << endl;
		DocWchUtils::StartDocResponderMode();
	}
}

/********************************************************************************************************************
 *****Function: SaveDocument
 *****Creator:  Vu Tiet
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::SaveDocument() {
	do {
		if(Utils<ILayoutUIUtils>() == nil)
		{
			cout << "SaveDocument break" << endl;
			break;
		}
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			cout << "--docFrom == NULL" << endl;
			break;
		}
		UIDRef  docRef = GetUIDRef(docFrom); 
		AMPUtils::SaveDocument(docRef);
		
	}while(kFalse);
}

void AMPUtils::SaveDocument(UIDRef documentUIDRef) {
	do {
		// Save the document to another file.
		if(documentUIDRef == UIDRef::gNull){
			break;
		}
		// Starting from InDesign 3.0, IDocumentUtils has been added to 
		// the utils boss where it is more logically placed. 
		// The version of IDocumentUtils on the session boss is being deprecated. 
		InterfacePtr<IDocFileHandler> docFileHandler(Utils<IDocumentUtils>()->QueryDocFileHandler(documentUIDRef));
		if (!docFileHandler) {
			cout << "docFileHandler break" << endl;
			break;
		}
		//Try to do Save
		//cout << "Try to do Save" << endl;
		docFileHandler->Save(documentUIDRef, K2::kSuppressUI);
		ErrorCode result = ErrorUtils::PMGetGlobalErrorCode();
		//ASSERT_MSG(result == kSuccess, "IDocFileHandler::Save failed");
		if (result != kSuccess) {
			cout << "save failed" << endl;
			break;
		}
		cout << "save succeed" << endl;
	} while(false);
}


/********************************************************************************************************************
 *****Function: ResetDocName
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::ResetDocName(UIDRef docRef) {
	
	if (AMPUtils::IsCheckedOutDoc(docRef) == TRUE) {
		// the current document was closed
		// reset g_DocName
		g_DocName = "";
	}
}


/********************************************************************************************************************
 *****Function: RefreshBrowseIssue
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::RefreshBrowseIssue()
{
	do
	{
		cout << "RefreshBrowseIssue()" << endl;
		/*
		InterfacePtr<IPanelControlData> 
		panelData(Utils<IPalettePanelUtils>()->QueryPanelByWidgetID(kBscSlDlgIssuesDialogWidgetID));	
		// Don't assert, fail silently, the tree view panel may be closed.
		if(panelData == nil)
		{
			cout << "error 1" << endl;
			break;
		}
		IControlView* treeWidget = panelData->FindWidget(kAMPIssuesTreeViewWidgetID);
		ASSERT(treeWidget);
		if(treeWidget == nil)
		{
			cout << "error 2" << endl;
			break;
		}
		*/
		//set expand widget
		if(Utils<IPalettePanelUtils>() == nil) {
			break;
		}
		InterfacePtr<IPanelControlData> panelControlData(Utils<IPalettePanelUtils>()->QueryPanelByWidgetID(kAMPIssuesTreeViewWidgetID));	
		// Don't assert, fail silently, the tree view panel may be closed.
		if(panelControlData == nil)
		{
			cout << "error 3" << endl;
			break;
		}
		// Set expander widget to hidden state if this node has no kids
		IControlView* expanderWidget = panelControlData->FindWidget(kTreeNodeExpanderWidgetID);
		ASSERT(expanderWidget);
		if(expanderWidget == nil) {
			break;
		}
		expanderWidget->Hide();
		//-->
		// redraw UI
		/*
		InterfacePtr<ITreeViewMgr> treeMgr(treeWidget, UseDefaultIID());
		treeMgr->ClearTree();
		treeMgr->ChangeRoot(kTrue);
		*/
	} while(kFalse);
}


/********************************************************************************************************************
 *****Function: IsCheckedOutDoc
 *****Creator:  Toan Nguyen
 *****IN:UIDRef docRef
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::IsCheckedOutDoc(UIDRef docRef) {
	bool result = FALSE;
	do {
		if (g_Package_id.length() < 1) {
			break;
		}
		
		/*
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			cout << "docFrom == NULL" << endl;
			break;
		}
		
		UIDRef  docRef = GetUIDRef(docFrom); 
		 */
		InterfacePtr<IDocument> iDocument (docRef, IID_IDOCUMENT); 
		if(iDocument == nil) {
			cout << "iDocument == nil" << endl;
			break; 
		}
		
		PMString docName; 
		iDocument->GetName(docName);
		//cout << "IsCheckedOutDoc g_DocName - currentDocName " << g_DocName << " - " << docName.GrabCString() << endl;
		if (g_DocName.compare(docName.GrabCString()) == 0) {
			result = TRUE;
		}
	} while (kFalse);
	return result;
}


/********************************************************************************************************************
 *****Function: CheckInAllStories
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::CheckInAllStories() {
	bool result = FALSE;
	do {
		if(Utils<ILayoutUIUtils>() == nil)
		{
			break;
		}
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			//cout << "docFrom == NULL" << endl;
			break;
		}
		UIDRef  docRef = GetUIDRef(docFrom); 
		result = AMPUtils::CheckInAllStories(docRef);
	} while (kFalse);
	
	return result;
}
/********************************************************************************************************************
 *****Function: CheckInAllStories
 *****Creator:  vU tIET
 *****IN:UIDRef docRef
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::CheckInAllStories(UIDRef docRef) {
	bool result = FALSE;
	do {
	
		InterfacePtr<IDocument> iDocument (docRef, IID_IDOCUMENT); 
		if(iDocument == nil) {
			cout << "iDocument == nil" << endl;
			break; 
		}
		
		PMString docName; 
		iDocument->GetName(docName);
		
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			cout << "storyList == nil" << endl;
			break;
		}
		
		result = TRUE;
		// Iterate over all the stories
		cout << "storyList->GetAllTextModelCount() = " << storyList->GetAllTextModelCount() << endl;
		for (int32 i = 0; i < storyList->GetAllTextModelCount(); i++ )
		{
			TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(i);
			
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			
			// get text frame UID
			InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
			WideString nameStr;
			compName->Get(nameStr);
			string compNameStr;
			StringUtils::ConvertWideStringToUTF8(nameStr, compNameStr);
			if(AMPUtils::PostCaptionImg(storyUIDRef, compNameStr) == kTrue)
			{
				continue;	// no need to check
			}
			// get index and story ID
			int storyIndex = -1;
			string storyID = "";
			for (int j = 0; j < g_TextFrameCount; j++) { 
				// only check in stories were edited by user
				if (g_TextFrames[j].textframeUID.compare(compNameStr) == 0 && g_TextFrames[j].isLocked == TRUE) {
					storyIndex = j;
					storyID = g_TextFrames[j].storyID;
					cout << "Story locked index: " << j << " || uid: " << compNameStr << " || Name: " << g_TextFrames[j].storyName << endl;
					break;
				}
			}
			
			// post checked out stories
			if (storyIndex < 0) {
				cout << "story can't check in index: " << i << " || uid: " << compNameStr << endl;
				continue;
			}
			cout << "ExportStoryToICML:" << storyID << endl;
			cout << "check in story: " << storyID << endl;
			// export story to icml
			AMPUtils::ExportStoryToICML(storyUIDRef, storyID);
			
			// do http request to post data 
			string pathFile = g_System_WorkspaceDir + "/" + storyID + ".icml";
			bool res = FALSE;
			//res = HTTPRequestHelper::PostStoryContentToCMS(storyID, pathFile, g_TextFrames[storyIndex].sessionID);
			res = HTTPRequestHelper::PostStoryContentToCMS(g_Issueid, storyID, pathFile, g_TextFrames[storyIndex].sessionID);
			
			if (res == TRUE) {
				// release lock 
				g_TextFrames[storyIndex].isLocked = FALSE;
				g_TextFrames[storyIndex].sessionID = "";
			}
			else {
				result = res;
			}
		} // iterate stories
		
	} while(kFalse);
	return result;
	
}
/********************************************************************************************************************
 *****Function: CheckInLastSelectedStory
 *****Creator:  Vu TIET
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::CheckInLastSelectedStory() {
	bool result = FALSE;
	do {
		if(Utils<ILayoutUIUtils>() == nil)
		{
			break;
		}
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			cout << "====docFrom == NULL" << endl;
			break;
		}
		UIDRef  docRef = GetUIDRef(docFrom); 
		
		InterfacePtr<IDocument> iDocument (docRef, IID_IDOCUMENT); 
		if(iDocument == nil) {
			cout << "iDocument == nil" << endl;
			break; 
		}
		
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			cout << "storyList == nil" << endl;
			break;
		}
		
		// Iterate over all the stories
		for (int32 i = 0; i < storyList->GetAllTextModelCount(); i++ )
		{
			TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(i);
			
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			
			// get index and story ID
			int storyIndex = -1;
			string storyID = "";
			for (int j = 0; j < g_TextFrameCount; j++) { 
				// only check in stories were edited by user
				if (g_TextFrames[j].textframeUID.compare(g_SelectedTextFrameUID) == 0 && g_TextFrames[j].isLocked == TRUE) {
					storyIndex = j;
					storyID = g_TextFrames[j].storyID;
					break;
				}
			}
			
			// post checked out stories
			if (storyIndex < 0) {
				break;
			}
			
			// export story to icml
			AMPUtils::ExportStoryToICML(storyUIDRef, storyID);
			
			// do http request to post data 
			string pathFile = g_System_WorkspaceDir + "/" + storyID + ".icml";
			//Bool8 res = HTTPRequestHelper::PostStoryContentToCMS(storyID, pathFile, g_TextFrames[storyIndex].sessionID);
			Bool8 res = HTTPRequestHelper::PostStoryContentToCMS(g_Issueid, storyID, pathFile, g_TextFrames[storyIndex].sessionID);
			
			// release lock
			g_TextFrames[storyIndex].isLocked = FALSE;
			g_TextFrames[storyIndex].sessionID = "";
			
			break;
			
		} // iterate stories
		
	} while(kFalse);
	return result;
	
}


/********************************************************************************************************************
 *****Function: ExportStoryToICML
 *****Creator:  Vu Tiet
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
ErrorCode AMPUtils::ExportStoryToICML(const UIDRef& storyUIDRef, const string icmlName) {
	ErrorCode result = kFailure;
	do {
		
		string ICMLexport = g_SDK_WorkspaceDir + ":" + icmlName + ".icml";
		//cout << "ICMLexport: " << ICMLexport << endl;
		PMString fileLocation(ICMLexport.c_str());
		IDFile exportFile(fileLocation);
		SDKFileHelper fileHelper(exportFile);
		
		InterfacePtr<IPMStream> stream(StreamUtil::CreateFileStreamWrite(exportFile, kOpenOut, 'TEXT', 'CWIE'));
		ASSERT(stream);
		if(!stream) {
			break;
		}
		stream->Open();
		if (stream->GetStreamState() != kStreamStateGood) {
			break;
		}
		
		stream->SetEndOfStream();
		//ASSERT(options.IsExpandedStructure());
		ASSERT(kINXExpanded.IsExpandedStructure());
		//result = Utils<ISnippetExport>()->ExportInCopyInterchange(stream, uidList);
		result = Utils<ISnippetExport>()->ExportInCopyInterchange(stream, UIDList(storyUIDRef));
		stream->Flush();
		ASSERT(result == kSuccess);
		stream->Close();

		//cout << "export completed" << endl;
	} while(false);
	
	return result;
}


/********************************************************************************************************************
 *****Function: FrontDocName
 *****Creator:  Toan Nguyen
 *****IN:UIDRef docRef
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
string AMPUtils::FrontDocName(UIDRef docRef) {
	string nameStr = "";
	do {
		IDocument *docFrom;
		if (docRef == UIDRef::gNull) {
			if(Utils<ILayoutUIUtils>() == nil)
			{
				break;
			}
			IDocument *_docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
			if (_docFrom == NULL ) {
				cout << "...docFrom == NULL" << endl;
				break;
			}
			docFrom = _docFrom;
		}else if (docRef != UIDRef::gNull)
		{
			InterfacePtr<IDocument>document(docRef, UseDefaultIID());
			if(!document) {
				cout << "--document = nil"<< endl;
				break;
			}
			docFrom = document;
		}
		PMString docName; 
		
		// reach the package id from hidden text
		do {
			InterfacePtr<IStoryList> storyList(docFrom, UseDefaultIID());
			ASSERT(storyList);
			if (!storyList) {
				break;
				//goto getfrontName_exit;
			}
			int textModelCount = storyList->GetAllTextModelCount();
			int beginRemoves[textModelCount];
			int endRemoves[textModelCount];
			
			textframes_t newTextFrames[storyList->GetAllTextModelCount()];
			int newTextFrameCount = 0;
			//cout << "GetStoryIDFromTextFrame iterate over all the stories: " << storyList->GetAllTextModelCount() << endl;
			for (int32 i = 0; i < textModelCount; i++ )
			{
				TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(i);
				
				// Get the text model of the story.
				UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
				InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
				ASSERT(textModel);
				if (!textModel) {
					break;
					//goto getfrontName_exit;
				}
				int32 totalLength = textModel->TotalLength();
				
				TextIterator begin(textModel, 0);
				TextIterator end(textModel, totalLength-1);
				PMString str("");
				
				int32 beginRemovedPos = -1;
				int32 endRemovedPos = -1;
				
				int32 beginRemovedSelf = -1;
				int32 endRemovedSelf = -1;
				
				for (TextIterator iter = begin; iter != end; iter++)
				{ 
					// get all content of textmodel
					const UTF32TextChar characterCode = *iter;
					PMString character;
					character.AppendW(characterCode);
					TextIndex position = iter.Position();
					str.Append(character.GrabCString());               
				}
				
				string iContent = str.GrabCString();
				
				// find textframe stores info 
				size_t start_info = iContent.find("Plugin_info::");
				size_t end_info = iContent.find("::Plugin_info");
				if (start_info != string::npos && end_info != string::npos) {
					
					string tempInfo = "Plugin_info::AudienceMediaInDesignPluginInformation::Plugin_info";
					iContent = iContent.substr(tempInfo.length(), iContent.length());
					tempInfo = "[[package_id]]";
					//cout << "Content jSON:" << iContent << endl;
					nameStr = JSONHelper::FindParamID(iContent, tempInfo);
					if (nameStr != "") {
						return nameStr;
					}else {
						cout << "No find package id from textframe" << endl;
						break;
					}
				}
			}
		}while(kFalse);
		// end of use docname from texframe
		
		//cout << "getfrontName" << endl;
		docFrom->GetName(docName);
		//cout << "TraceBoss docName: " << docName.GrabCString() << endl;
		nameStr = docName.GrabCString();
		
	} while (kFalse);
	return nameStr;
}


/********************************************************************************************************************
 *****Function: UnlockStories
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::UnlockStories() {
	bool res = TRUE;
	bool requestRes = TRUE;
	for (int i = 0; i < g_TextFrameCount; i++) {
		if (g_TextFrames[i].isLocked == TRUE) {
			// request to unlock URL
			//requestRes = HTTPRequestHelper::UnlockStory(g_TextFrames[i].storyID);
			requestRes = HTTPRequestHelper::UnlockStory(g_Issueid, g_TextFrames[i].storyID);
			if (requestRes == FALSE) 
				res = requestRes;
		}
	}
	return res;
}


/********************************************************************************************************************
 *****Function: UnlockPackage
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::UnlockPackage() {
	//return HTTPRequestHelper::UnlockPackage(g_Package_id);
	return HTTPRequestHelper::UnlockPackage(g_Issueid, g_pageNumberCheckOut);
}


/********************************************************************************************************************
 *****Function: ClearAllFile
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::ClearAllFile()
{
	string CleanStr;
	// clear all file after check in
	//	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -r -f *";
	//	system(CleanStr.c_str());
	AMPUtils::RefreshMainPanel(FALSE);
	// clear file log
	CleanStr = "rm -f " + g_System_logDirectory + "/" + g_Username + "@" + g_Domain;
	system(CleanStr.c_str());
	//cout << "CleanStr: " << CleanStr << endl;
	
	FILE *fn;
	string sessionInfoPath;
	
	sessionInfoPath = g_System_WorkspaceDir + "/" + g_Username + ".info";
	//cout << "sessionInfoPath: " << sessionInfoPath << endl;
	
	fn = fopen(sessionInfoPath.c_str(), "wb");
	if (fn == NULL) {
		fclose(fn);
		return FALSE;
	}
	
	fprintf(fn, "#Audience Media Header Record#\r\n");
	//fprintf(fn, "Session id : %s\r\n", n_mSessionID.c_str());
	fprintf(fn, "Unlock stories: %s\r\n", g_UnlockStories.c_str());
	
	fclose(fn);
/*	
	PMString getname;
	PMString FrontName(g_DocName.c_str());
	do {
		InterfacePtr<IApplication> application(GetExecutionContextSession()->QueryApplication());
		if (application == NULL ) {
			cout << "...application == NULL" << endl;
			break;
		}
		InterfacePtr<IDocumentList> documentList(application->QueryDocumentList());
		if (documentList == NULL ) {
			cout << "...documentList == NULL" << endl;
			break;
		}
		
		for (int xx = 0; xx < documentList->GetDocCount(); xx++)
		{
			IDocument* document = documentList->GetNthDoc(xx);
			if (document == NULL ) {
				cout << "...document == NULL" << endl;
				break;
			}
			
			document->GetName(getname);
			if(FrontName == getname) {
				string StrCheckedIn = g_DocName + "checkedIn";
				document->SetName(PMString(StrCheckedIn.c_str()));
				break;
			}
			
		}
	} while (kFalse);
	/*
	if(Utils<ILayoutUIUtils>() == nil)
	{
		return FALSE;
	}
	IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
	if (docFrom == NULL ) {
		cout << "==>docFrom == NULL" << endl;
		return FALSE;
	}
	
	UIDRef  docRef = GetUIDRef(docFrom); 
	InterfacePtr<IDocument> iDocument (docRef, IID_IDOCUMENT); 
	if(iDocument == nil) {
		cout << "iDocument == nil" << endl;
		return FALSE;
	}
	string StrCheckedIn = g_DocName + "checkedIn";
	iDocument->SetName(PMString(StrCheckedIn.c_str()));
	 */
//	CleanStr = "cd " + g_System_WorkspaceDir + " && tar -xvf " + MediaLib + ".zip";
//	system(CleanStr.c_str());
	
	//CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + MediaLib + ".zip";
	//system(CleanStr.c_str());
	
	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.zip";
	system(CleanStr.c_str());
	
//	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.jpg";
//	system(CleanStr.c_str());
	
//	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.icml";
//	system(CleanStr.c_str());
	
//	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.idml";
//	system(CleanStr.c_str());
	
//	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.indd";
//	system(CleanStr.c_str());
	
	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.icma";
	system(CleanStr.c_str());
	
	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.idlk";
	system(CleanStr.c_str());
	
	if(g_LinkInfo.size() > 0) {
		g_LinkInfo.clear();
	}
	
	if(g_assignmentPtr.size() > 0) {
		g_assignmentPtr.clear();
	}
	
	if(g_captionImg.size() > 0) {
		g_captionImg.clear();
	}
	
	InitLogCenter(TRUE);
	return TRUE;
}

/********************************************************************************************************************
 *****Function: InitSessionCounter
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::InitSessionCounter()
{
	n_mSessionCounterReset = 0;
	n_mSessionTotalCounterReset = 18000; // default time will reset in 5 hours = 5 * 60 * 60
}

/********************************************************************************************************************
 *****Function: RenewLogFilePath
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::RenewLogFilePath() {
	FSRef ref;
	OSType folderType = kCurrentUserFolderType;
	
	char pathSave[400];
	FSFindFolder( kUserDomain, folderType, kCreateFolder, &ref);
	FSRefMakePath(&ref, (uint8*)&pathSave, 400);
	//cout << "get Path: " << pathSave << endl;
	string logPath(pathSave);	//Users/currentUserLogin
	g_System_logDirectory = logPath + "/" + ".adobe" /*+ "/" + g_Username +".txt"*/;
}

/********************************************************************************************************************
 *****Function: RenewWorkspaceDir
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
int AMPUtils::RenewWorkspaceDir() {
	FSRef ref;
	OSType folderType = kCurrentUserFolderType;
	
	char pathSave[400];
	FSFindFolder( kUserDomain, folderType, kCreateFolder, &ref);
	FSRefMakePath(&ref, (uint8*)&pathSave, 400);
	cout << "get Path: " << pathSave << endl;
	string RENEWWORKSPACE = "/" + g_Username;
	string tmpPath(pathSave);	//Users/currentUserLogin
	string excutePath("mkdir ");
	tmpPath += "/";
	tmpPath += WORKSPACE_DIR; //Users/currentUserLogin/AMPInDesignPlugin/username/
	tmpPath += "/" + g_Username + "@" + g_Domain;	//Users/currentUserLogin/AMPInDesignPlugin/username@domain/
	excutePath += tmpPath;     
	system(excutePath.c_str()); //mkdir path
	g_System_WorkspaceDir = tmpPath;
	cout << "Path: " << g_System_WorkspaceDir << " User: " << RENEWWORKSPACE << endl;
	// create g_SDK_WorkspaceDir by get volume name and replace "/" by ":"
	char *volname = NULL;
	AMPUtils::volumeNameForPath(tmpPath.c_str(), &volname);
	//printf("volname: %s\n", volname);
	
	g_SDK_WorkspaceDir.assign(volname); // volume name 
	while (tmpPath.find("/") != string::npos) {
		tmpPath.replace(tmpPath.find("/"), 1, ":"); // replace "/" by ":"
	}
	
	g_SDK_WorkspaceDir += tmpPath; // example: Macintosh HD:Users:vutiet:AMPInDesignPlugin
	
	//cout << "g_WorkspaceDir " << g_WorkspaceDir << endl;
	DisposePtr(volname);

	//Create local directory to store log file
	string logPath(pathSave);	//Users/currentUserLogin
	string logDirectory = "mkdir " + logPath + "/" + ".adobe";
	system(logDirectory.c_str()); //mkdir path
	
	g_System_logDirectory = logPath + "/" + ".adobe";
	
	// create g_SDK_LogspaceDir by get volume name and replace "/" by ":"
	volname = NULL;
	tmpPath = g_System_logDirectory;
	AMPUtils::volumeNameForPath(tmpPath.c_str(), &volname);
	//cout << "tmpPath " << tmpPath << endl;
	//cout << "volname " << volname << endl;
	g_SDK_logDirectory.assign(volname); // volume name 
	while (tmpPath.find("/") != string::npos) {
		tmpPath.replace(tmpPath.find("/"), 1, ":"); // replace "/" by ":"
	}
	
	g_SDK_logDirectory += tmpPath; // example: Macintosh HD:Users:vutiet:AMPInDesignPlugin
	// Hidden folder
	excutePath = "chflags hidden " + g_System_WorkspaceDir;
	system(excutePath.c_str());
	//cout << "g_SDK_logDirectory " << g_SDK_logDirectory << endl;
	
	excutePath = "Workspace:" + g_System_WorkspaceDir;
	SaveLogCenterData(excutePath);
	excutePath = "Loggingspace:" + g_System_logDirectory;
	SaveLogCenterData(excutePath);
	return 0;
}

/********************************************************************************************************************
 *****Function: RenewSessionID
 *****Creator:  Toan Nguyen
 *****IN:string Session_id
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::RenewSessionID(string Session_id) {
	bool result = FALSE;
	
	// Request new session id from CMS
	string newSessionID = HTTPRequestHelper::RenewSession(Session_id);
	
	if (newSessionID.length() > 0) {
		n_mSessionID = newSessionID;
		result = TRUE;
	}
	else {
		n_mSessionID = "";
		result = FALSE;
	}
	
	// save new session info
	SaveSessionInfo();
	
	// save log file
	SaveLogHeaderFile();
	
	return result;
}

/********************************************************************************************************************
 *****Function: SetNameDocument
 *****Creator:  Toan Nguyen
 *****IN:string IDName
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::SetNameDocument(string IDName) {
	
	do {
		if(g_DocName == "") {
			break;
		}
		if(Utils<ILayoutUIUtils>() == nil)
		{
			break;
		}
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			cout << "<-->docFrom == NULL" << endl;
			break;
		}
		
		UIDRef  docRef = GetUIDRef(docFrom); 
		InterfacePtr<IDocument> iDocument (docRef, IID_IDOCUMENT); 
		if(iDocument == nil) {
			cout << "iDocument == nil" << endl;
			break; 
		}
		cout << "Setname document: " << IDName << endl;
		iDocument->SetName(PMString(IDName.c_str()));
		
		return TRUE;
		
	}while(kFalse);
	
	return FALSE;
}

/********************************************************************************************************************
 *****Function: ClearPackageAndSessionInfo
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::ClearPackageAndSessionInfo()
{
	g_TextSelected = FALSE;
	g_PrevTextSelected = FALSE;
	g_SelectedTextFrameUID = "";
	g_TextFrameCount = 0;
	g_Magazineid = "";
	g_Issueid = "";
	g_Pageid = "";
	g_Storyid = "";
	g_IDMLzip = "";
	g_Package_id = "";
	g_DocName = "";
	
	n_mSessionID = "";
	n_mSessionTimeOut = 0;
	n_mSessionTotalCounterReset = 18000; // default time will reset in 5 hours = 5 * 60 * 60
	n_mSessionUserID = "";
	g_pageNumberCheckOut = "";
	g_CurPreviewImaPath = "";
	g_CurPreviewNodeName = "";
	g_CanCheckIn = FALSE;
	g_pageEditing = "";
	g_issueEditing = "";
	g_pageCheckIn = "";
	//SaveLogCenterData("---------Progress working completely----------");
	//SaveSessionInfo();
	AMPUtils::IssueListRefresh();
	return TRUE;
}

/********************************************************************************************************************
 *****Function: ClearUserInfo
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::ClearUserInfo() {
	g_IsLoggedIn = FALSE;
	g_Password = "";
	g_Authentication = "";
	g_SDK_WorkspaceDir = "";
	g_System_WorkspaceDir = "";
	return TRUE;
}

/********************************************************************************************************************
 *****Function: RemoveIDFromTextFrames
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::RemoveIDFromTextFrames() {
	do {
		if(Utils<ILayoutUIUtils>() == nil)
		{
			break;
		}
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			//cout << "docFrom == NULL" << endl;
			break;
		}
		UIDRef  docRef = GetUIDRef(docFrom); 
		AMPUtils::RemoveIDFromTextFrames(docRef);
	} while (kFalse);
}

/********************************************************************************************************************
 *****Function: RemoveIDFromTextFrames
 *****Creator:  Toan Nguyen
 *****IN:UIDRef docRef
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::RemoveIDFromTextFrames(UIDRef docRef) {
	do {
		
		//UIDRef  docRef = GetUIDRef(docFrom); 
		InterfacePtr<IDocument> iDocument (docRef, IID_IDOCUMENT); 
		if(iDocument == nil) {
			//cout << "iDocument == nil" << endl;
			break; 
		}
	
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			//cout << "storyList == nil" << endl;
			break;
		}
		
		textframes_t newTextFrames[storyList->GetAllTextModelCount()];
		int newTextFrameCount = 0;
		cout << "RemoveIDFromTextFrames iterate over all the stories: " << storyList->GetAllTextModelCount() << endl;
		SnpTextModelHelper	textCmdHelper;
		int32 beginRemovedPos = -1;
		int32 endRemovedPos = -1;
		//PMString replacePMS("");
		//WideString replaceWS(replacePMS);
		//boost::shared_ptr<WideString>	wideReplace(new WideString(replaceWS));
		for (int32 i = 0; i < storyList->GetAllTextModelCount(); i++ )
		{
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			
			InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
			WideString nameStr;
			compName->Get(nameStr);
			string tmp;
			StringUtils::ConvertWideStringToUTF8(nameStr, tmp);
			
			for (int j = 0; j < g_TextFrameCount; j++) {
				if (g_TextFrames[j].textframeUID == tmp) {
					// remove story ID and package ID from text model
					cout << "Remove stories: " << j << " - (start-end):" << g_TextFrames[j].beginRemovePos << g_TextFrames[j].endRemovePos << endl;
					textCmdHelper.DeleteText(textModel, g_TextFrames[j].beginRemovePos, g_TextFrames[j].endRemovePos);
					break;
				}
			}
			
			
			/*
			//cout << "++++++story: " << i << endl;
			beginRemovedPos = -1;
			endRemovedPos = -1;
			TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(i);
			
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			int32 totalLength = textModel->TotalLength();
			//cout << "story length " << i << ": " << totalLength << endl;
			//int32 primaryStoryThreadSpan = textModel->GetPrimaryStoryThreadSpan();
			
			TextIterator begin(textModel, 0);
			TextIterator end(textModel, totalLength-1);
			PMString str("");
			
			for (TextIterator iter = begin; iter != end; iter++)
			{ 
				// get all content of textmodel
				const UTF32TextChar characterCode = *iter;
				PMString character;
				character.AppendW(characterCode);
				TextIndex position = iter.Position();
				str.Append(character.GrabCString());               
			}
			
			
			string iContent = str.GrabCString();
			//cout << "iContent: " << iContent << endl;
			size_t beginPackagePos = iContent.find("[[[idml_name]]]");
			size_t endPackagePos = iContent.find("[[[/idml_name]]]");
			//cout << "beginPackagePos - endPackagePos: " << beginPackagePos << " - " << endPackagePos << endl;
			//cout << "beginRemovedPos - endRemovedPost: " << beginRemovedPos << " - " << endRemovedPos << endl;
			if (beginPackagePos != string::npos && endPackagePos != string::npos) {
				beginRemovedPos = beginPackagePos;
				endRemovedPos = endPackagePos+16-1; // length of [[[/idml_name]]] is 16
			}
			//cout << "GetIDFromTextFrame g_Package_id - g_DocName: " << g_Package_id << " - " << g_DocName << endl;
			
			size_t beginStoryPos = iContent.find("[[[story_id]]]");
			size_t endStoryPos = iContent.find("[[[/story_id]]]");
			//cout << "beginStoryPos - endStoryPos: " << beginStoryPos << " - " << endStoryPos << endl;
			//cout << "beginRemovedPos - endRemovedPost: " << beginRemovedPos << " - " << endRemovedPos << endl;
			if (beginStoryPos != string::npos && endStoryPos != string::npos) {
				if (beginStoryPos < beginRemovedPos || beginRemovedPos == -1) {
					beginRemovedPos = beginStoryPos;
				}
				if (endStoryPos > endRemovedPos || endRemovedPos == -1) {
					endRemovedPos = endStoryPos+15-1; // length of [[[/story_id]]] is 15
				}
			}
			
			// remove story ID and package ID from text model
			textCmdHelper.DeleteText(textModel, beginRemovedPos, (endRemovedPos-beginRemovedPos+1));
			cout << "remove from: " << beginRemovedPos << " to: " << (endRemovedPos-beginRemovedPos+1) << endl;
			cout << "end loop story: " << i << endl;
			 */
			
		} // iterate stories
		
	} while (kFalse);
}

/********************************************************************************************************************
 *****Function: HandleQuickSortString
 *****Creator:  Toan Nguyen
 *****IN:string img_nodename_checkout, string img_path_checkout, string page_check_out
 *****out: 
 *****Objective: order string
 ********************************************************************************************************************/
void AMPUtils::HandleQuickSortString(string img_nodename_checkout, string img_path_checkout, string page_check_out){
	/*
	//string img_path_checkout = //"image_path_page_1, image_path_page_3, image_path_page_10, image_path_page_12, image_path_page_8, \
															image_path_page_9, image_path_page_2, image_path_page_4, image_path_page_5, image_path_page_7, \
															image_path_page_6, image_path_page_11,";
	//string page_check_out = //" 1, 3, 10, 12, 8, 9, 2, 4, 5, 7, 6, 11,";
	 */
	int xx, length_allocate = 1;
	for(xx = 0; xx < page_check_out.length(); xx++)
	{
		if(page_check_out[xx] == ',')
			length_allocate++;
	}
	//cout << "page_check_out:" << page_check_out << endl;
	//cout << "length_allocate:" << length_allocate << endl;
	
	string img_path_convert[length_allocate];
	string img_nodename_convert[length_allocate];
	
	int array_num[length_allocate];
	int length_array = 0;
	int length_num_after_find = 0;
	int length_page_after_find = 0;
	int length_node_after_find = 0;
	
	string n_CurPreviewNodeName = "";
	string n_CurPreviewImaPath = "";
	string n_pageNumberCheckOut = "";
	
	while (kTrue) {
		if((img_path_checkout == "") || (page_check_out == "") || (length_array >= length_allocate))
			break;
		length_node_after_find = img_nodename_checkout.find(",");
		length_num_after_find = page_check_out.find(",");
		length_page_after_find = img_path_checkout.find(";");
		
		array_num[length_array] = atoi(page_check_out.c_str());
		page_check_out = page_check_out.erase(0, length_num_after_find + 1);
		
		img_path_convert[length_array] = img_path_checkout.substr(0, length_page_after_find + 1);
		img_path_checkout = img_path_checkout.erase(0, length_page_after_find + 1);
		//cout << "array_num[" << length_array << "] :" << array_num[length_array] << endl;
		//cout << "img_path_convert[" << length_array << "] :" << img_path_convert[length_array] << endl;
		
		img_nodename_convert[length_array] = img_nodename_checkout.substr(0, length_node_after_find + 1);
		img_nodename_checkout = img_nodename_checkout.erase(0, length_node_after_find + 1);
		++length_array;
	}
	
	int curChange, curValue;
	int smallest;
	int position_smallest = 0;
	// find position smallest in array
	for (curValue = 0; curValue < length_array; curValue++)
	{
		//cout << "===array_num[" << curValue << "] :" << array_num[curValue] << endl;
		//cout << "===img_path_convert[" << curValue << "] :" << img_path_convert[curValue] << endl;
		smallest = array_num[curValue];
		for (curChange = curValue; curChange < length_array; curChange++)
		{
			if(smallest > array_num[curChange])
			{
				smallest = array_num[curChange];
				position_smallest = curChange;
			}
		}
		// swap position smallest and current number
		if(smallest != array_num[curValue])
		{
			int tmp_change = array_num[curValue];
			array_num[curValue] = array_num[position_smallest];
			array_num[position_smallest] = tmp_change;
			
			// convert path string
			string tmp_strchange = img_path_convert[curValue];
			img_path_convert[curValue] = img_path_convert[position_smallest];
			img_path_convert[position_smallest] = tmp_strchange;
			
			//convert image nodename
			tmp_strchange = img_nodename_convert[curValue];
			img_nodename_convert[curValue] = img_nodename_convert[position_smallest];
			img_nodename_convert[position_smallest] = tmp_strchange;
		}
		stringstream outstr;
		outstr << array_num[curValue];
		
		n_pageNumberCheckOut = n_pageNumberCheckOut + " " + outstr.str() + ",";
		n_CurPreviewImaPath = n_CurPreviewImaPath + img_path_convert[curValue];
		n_CurPreviewNodeName = n_CurPreviewNodeName + img_nodename_convert[curValue];
	}
	
	g_pageNumberCheckOut = n_pageNumberCheckOut;
	g_CurPreviewImaPath = n_CurPreviewImaPath;
	g_CurPreviewNodeName = n_CurPreviewNodeName;
	//cout << "----g_pageNumberCheckOut = " << g_pageNumberCheckOut << endl;
	//cout << "----g_CurPreviewImaPath = " << g_CurPreviewImaPath << endl;
	//cout << "----g_CurPreviewNodeName = " << g_CurPreviewNodeName << endl;
}

/********************************************************************************************************************
 *****Function: AddStoriesToUnlockQueue
 *****Creator:  Vu Tiet
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::AddStoriesToUnlockQueue() {
	for (int i = 0; i < g_TextFrameCount; i++) {
		if (g_TextFrames[i].isLocked == TRUE) {
			if (g_UnlockStories.find(g_TextFrames[i].storyID) == string::npos) {
				g_UnlockStories = g_UnlockStories + g_TextFrames[i].storyID + ",";
			}
		}	
	}
}

void AMPUtils::AddPackagesToUnlockQueue() {

}

/********************************************************************************************************************
 *****Function: UnlockStoriesInQueue
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::UnlockStoriesInQueue() {
	bool res = TRUE;
	bool requestRes = TRUE;
	for (int i = 0; i < g_TextFrameCount; i++) {
		if (g_TextFrames[i].isLocked == TRUE) {
			if (g_UnlockStories.find(g_TextFrames[i].storyID) != string::npos) {
				//requestRes = HTTPRequestHelper::UnlockStory(g_TextFrames[i].storyID);
				requestRes = HTTPRequestHelper::UnlockStory(g_Issueid, g_TextFrames[i].storyID);
				if (requestRes == FALSE) {
					res = requestRes;
				}
				else {
					g_UnlockStories.replace(g_UnlockStories.find(g_TextFrames[i].storyID.c_str()), g_TextFrames[i].storyID.length()+1, "");
				}
			}
		}
	}
	
	while (g_UnlockStories.find(",") != string::npos) {
		string unlockStoryID = g_UnlockStories.substr(g_UnlockStories.find(","));
		//requestRes = HTTPRequestHelper::UnlockStory(unlockStoryID);
		requestRes = HTTPRequestHelper::UnlockStory(g_Issueid, unlockStoryID);
		if (requestRes == FALSE) {
			res = requestRes;
		}
		else {
			g_UnlockStories = g_UnlockStories.substr(g_UnlockStories.find(","));
		}
	}
	
	return res;
}


bool AMPUtils::UnlockPackagesInQueue() {
	return TRUE;
}


/********************************************************************************************************************
 *****Function: CloseCurDocument
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: close document after check in pages
 ********************************************************************************************************************/
void AMPUtils::CloseCurDocument()
{	
	SDKLayoutHelper iLayoutHelper;
	if(Utils<ILayoutUIUtils>() == nil)
	{
		cout << "Cannot Utils<ILayoutUIUtils>()" << endl;
		return;
	}//

	IDocument* CurDocument = Utils<ILayoutUIUtils>()->GetFrontDocument();
	// +precondition
	ASSERT(CurDocument);
	if(!CurDocument) {
		cout << "Cannot load document" << endl;
		return;
	}
	//cout << "g_DocName - AMPUtils::FrontDocName():" << g_DocName << AMPUtils::FrontDocName() << endl;
	//AMPDocument::RelinkICML(CurDocument);
	UIDRef docRef = GetUIDRef(CurDocument); 
	if(g_DocName.compare(AMPUtils::FrontDocName()) == 0) {
		//cout << "++Close document" << endl;
		//cout << "++Close document with low priority" << endl;
		iLayoutHelper.CloseDocument(docRef, kFalse, K2::kSuppressUI, kTrue, IDocFileHandler::kSchedule);
		//iLayoutHelper.~SDKLayoutHelper();
		//cout << "--Close document" << endl;
	}else {
		cout << "--Not workspace document working" << endl;
	}
}

/********************************************************************************************************************
 *****Function: FindFrontDocsName
 *****Creator:  Toan Nguyen
 *****IN:PMString FrontName
 *****out: 
 *****Objective: find package id from all documents
 ********************************************************************************************************************/
bool AMPUtils::FindFrontDocsName(PMString FrontName) {
	PMString getname;
	do {
		InterfacePtr<IApplication> application(GetExecutionContextSession()->QueryApplication());
		if (application == NULL ) {
			cout << "...application == NULL" << endl;
			break;
		}
		InterfacePtr<IDocumentList> documentList(application->QueryDocumentList());
		if (documentList == NULL ) {
			cout << "...documentList == NULL" << endl;
			break;
		}
		
		for (int xx = 0; xx < documentList->GetDocCount(); xx++)
		{
			IDocument* document = documentList->GetNthDoc(xx);
			if (document == NULL ) {
				cout << "...document == NULL" << endl;
				break;
			}
			
			document->GetName(getname);
			//cout << "FrontName:" << getname.GrabCString() << endl;
			if(FrontName == getname) {
				return TRUE;
			}
			
		}
		return FALSE;
		
	} while (kFalse);
 
	return FALSE;
}

/********************************************************************************************************************
 *****Function: CheckinWhenLogout
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
bool AMPUtils::CheckinWhenLogout()
{
	do {
		
		PMString alertStr("\n\nBefore you sign-out, would you like to check-in and save changes?");
		int16 result = AMPCAlert::ModalAlert
		(
		 alertStr,
		 kYesString,					// YES
		 kNoString, 					// NO
		 kCancelString,					// CANCEL
		 kNeedToWaitForDialog,			// Set kNeedToWaitForDialog to default
		 1								// No icon.
		 );
		
		if (result == kOKSystem) // YES
		{
			bool idmlCheckinSuccess = FALSE;
			//bool storiesCheckinSuccess = FALSE;
			//storiesCheckinSuccess = AMPUtils::CheckInAllStories();
			
			bool shouldPost = TRUE;
			
			if (shouldPost == TRUE) {
				idmlCheckinSuccess = AMPDocument::CheckinDocsWorking(g_DocName.c_str());
				
			}
			
			if (/*storiesCheckinSuccess == TRUE && */idmlCheckinSuccess == TRUE) {
				// Reset variables
				AMPUtils::ClearAllFile();
				AMPUtils::CloseCurDocument();	//added to close document 20121016
			}
			else {
				AMPCAlert::ModalAlert
				(
				 PMString("\n\nBefore you sign-out, would you like to check-in and save changes?"),	// Alert string
				 "OK",							// OK button
				 kNullString, 					// No second button
				 kNullString, 					// No third button
				 kNoNeedToWaitForDialog,		// Set OK button to default
				 1								// No icon.
				 );
			}
			AMPUtils::CloseCurDocument();	//added to close document 20121016
			AMPUtils::ClearPackageAndSessionInfo();
			//ResetGlobalValue();
			AMPUtils::ClearUserInfo();
			AMPUtils::RefreshMainPanel(FALSE);
			
		}
		else if (result == kCancelSystem) // NO
		{
			//cout << "No selected" << endl;
			// unlock package and stories
			bool res = FALSE;
			res = AMPUtils::UnlockStories();
			if (res == FALSE) {
				// add to action queue
			}
			res = AMPUtils::UnlockPackage();
			if (res == FALSE) {
				// add to action queue
			}
			else {
				// Clean up
				AMPUtils::ClearAllFile();
				AMPUtils::CloseCurDocument();	//added to close document 20121016
				AMPUtils::ClearPackageAndSessionInfo();
				AMPUtils::ClearUserInfo();
				AMPUtils::RefreshMainPanel(FALSE);
				
			}
		}
		
	} while(kFalse);
	
	return TRUE;
}

/********************************************************************************************************************
 *****Function: StoryInfoHiddenSetting
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: set hidden story info
 ********************************************************************************************************************/
bool AMPUtils::StoryInfoHiddenSetting(bool finish) {
	do {
		string contentInfo;
		SDKLayoutHelper layoutHelper;
		//cout << "StoryInfoHiddenSetting() start" << endl;
		IDocument *docFrom = Utils<ILayoutUIUtils>()->GetFrontDocument(); 
		if (docFrom == NULL ) {
			cout << "docFrom == NULL" << endl;
			break;
		}
		
		UIDRef docRef = GetUIDRef(docFrom);
		UIDRef storyUIDRef;
		
		InterfacePtr<ISpreadList> spreadList(docRef, UseDefaultIID());
		if(!spreadList) {
			break;
		}
		
		UIDRef spreadRef = UIDRef(docRef.GetDataBase(), spreadList->GetNthSpreadUID(0));
		UIDRef storyInfo = AMPUtils::GetIDTextFrameInfo(docFrom, contentInfo);
		
		if(storyInfo == UIDRef::gNull)
		{
			//bounds(-1500, -1000, -1190, -490);  //left, top, right, bottom;
			int32 numberOfColumns = 1;
			bool16 verticalFrame = kFalse;
			
			InterfacePtr<IGeometry> __iGeometryImagen (spreadRef, IID_IGEOMETRY);
			if(!__iGeometryImagen) {
				break;
			}
			
			PMRect sizes  = __iGeometryImagen->GetStrokeBoundingBox();
			cout << "left:" << ToDouble(sizes.Left()) << endl;
			cout << "top:" << ToDouble(sizes.Top()) << endl;
			cout << "right:" << ToDouble(sizes.Right()) << endl;
			cout << "bottom:" << ToDouble(sizes.Bottom()) << endl;
			
			PMRect bounds(ToDouble(sizes.Left()) - 550.0, ToDouble(sizes.Top()) - 450.0, ToDouble(sizes.Left()), ToDouble(sizes.Top()));
			
			UIDRef spreadLayerRef = layoutHelper.GetActiveSpreadLayerRef(spreadRef);
			UIDRef frameRef = layoutHelper.CreateTextFrame(spreadLayerRef,
														   bounds,
														   numberOfColumns,
														   verticalFrame,
														   &storyUIDRef);

			AMPIconFrameUpdate::LockPageItem(frameRef);
			Utils<Facade::IPageItemVisibilityFacade>()->Hide(frameRef);
		}else
		{
			//cout << "storyInfo != UIDRef::gNull" << endl;
			// move textframe to hidden
			storyUIDRef = storyInfo;
			/*
			InterfacePtr<ITransform> transform(parentUIDRef, UseDefaultIID());
			ASSERT(transform);
			if (transform == nil) {
				break;
			}
			::TransformParentPointToPasteboard(transform, &topLeft);
			::TransformParentPointToPasteboard(transform, &rightBottom);
			
			//PMRect sizes  = iGeometryImagen->GetStrokeBoundingBox();
			cout << "left:" << ToDouble(lImageBBox.Left()) << endl;
			cout << "top:" << ToDouble(lImageBBox.Top()) << endl;
			cout << "right:" << ToDouble(lImageBBox.Right()) << endl;
			cout << "bottom:" << ToDouble(lImageBBox.Bottom()) << endl;
			 */
		}
		
		InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
		ASSERT(textModel);
		if (!textModel) {
			break;
		}
		
		// ipTextModel - >this is an interface <ITextModel> 
		InterfacePtr<IItemLockData> ipTextLockData(textModel, UseDefaultIID()); 
		if(ipTextLockData == nil) 
		{ 
			break; 
		}
		
		ipTextLockData->SetInsertLock(kFalse);  // unlock
		ipTextLockData->SetAttributeLock(kFalse);  // unlock
		
		/*
		string tempInfo = "[[[Plugin_info]]]AudienceMediaInDesignPluginInformation[[[/Plugin_info]]]";
		string storyIDStr = tempInfo;
		if (finish == kFalse) {
			storyIDStr = tempInfo + JSONHelper::AMPluginSetInfoMap();
		}else if (finish == kTrue){
			storyIDStr = "[[info]]********DELETE********[[/info]]";
		}
		cout << "storyIDStr:" << storyIDStr << endl;
		PMString storyIDPMStr(storyIDStr.c_str());
		WideString storyIDWStr(storyIDPMStr);
		boost::shared_ptr<WideString>	_wide(new WideString(storyIDWStr));
		SnpTextModelHelper	textCmdHelper;
		//textCmdHelper.DeleteText(_textModel, 0, _textModel->TotalLength()-1);
		textCmdHelper.InsertText(_textModel, 0, _wide);
		 */
		//string tempInfo = "[[[Plugin_info]]]AudienceMediaInDesignPluginInformation[[[/Plugin_info]]]";
		string tempInfo = "Plugin_info::AudienceMediaInDesignPluginInformation::Plugin_info" + JSONHelper::AMPluginSetInfoMap();
		string storyIDStr = tempInfo;
		PMString storyIDPMStr(storyIDStr.c_str());
		WideString storyIDWStr(storyIDPMStr);
		boost::shared_ptr<WideString>	wide(new WideString(storyIDWStr));
		SnpTextModelHelper	textCmdHelper;
		textCmdHelper.DeleteText(textModel, 0, textModel->TotalLength()-1);
		textCmdHelper.InsertText(textModel, 0, wide);
		ipTextLockData->SetInsertLock(kTrue);  // lock
		ipTextLockData->SetAttributeLock(kTrue);  // lock
		
		//PageItemLockSuite
		//cout << "StoryInfoHiddenSetting() end" << endl;
		
		/////
		/*
		InterfacePtr<ISelectionManager> selectionManager(Utils<ISelectionUtils>()->QueryActiveSelection());
		selectionManager->DeselectAll(nil);
		
		 Use to point move to textframe
		// Make a text selection to set the text caret blinking at the start of the story.
		InterfacePtr<ITextSelectionSuite> textSelectionSuite(selectionManager, UseDefaultIID());
		if (!textSelectionSuite) {
			break;
		}
		textSelectionSuite->SetTextSelection(storyUIDRef, RangeData(0, RangeData::kLeanForward), Selection::kScrollIntoView, nil); // scrollTo
		*/
		/////
		return kTrue;
		
	}while(kFalse);
	cout << "storyInfo = UIDRef::gNull" << endl;
	return kFalse;
}

/********************************************************************************************************************
 *****Function: GetStoryInfoContent
 *****Creator:  Toan Nguyen
 *****IN:UIDRef storyInfo
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::GetStoryInfoContent(UIDRef storyInfo)
{
	do {
		if(storyInfo == UIDRef::gNull)
		{
			break;
		}
		UIDRef storyUIDRef = storyInfo;
		
		InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
		ASSERT(textModel);
		if (!textModel) {
			break;
		}
		int32 totalLength = textModel->TotalLength();
		//int32 primaryStoryThreadSpan = textModel->GetPrimaryStoryThreadSpan();
		
		TextIterator begin(textModel, 0);
		TextIterator end(textModel, totalLength-1);
		PMString str("");
		
		int32 beginRemovedPos = -1;
		int32 endRemovedPos = -1;
		
		int32 beginRemovedSelf = -1;
		int32 endRemovedSelf = -1;
		
		for (TextIterator iter = begin; iter != end; iter++)
		{ 
			// get all content of textmodel
			const UTF32TextChar characterCode = *iter;
			PMString character;
			character.AppendW(characterCode);
			TextIndex position = iter.Position();
			str.Append(character.GrabCString());               
		}
		
		string iContent = str.GrabCString();
		string tempInfo = "Plugin_info::AudienceMediaInDesignPluginInformation::Plugin_info";
		if(iContent != tempInfo) {
			iContent = iContent.substr(tempInfo.length(), iContent.length());
			JSONHelper::AMPluginGetInfoMap(iContent);
		}
	}while(kFalse);
}

void AMPUtils::ResetFrontNameDoc(string Name){
}

/********************************************************************************************************************
 *****Function: ResetLogFile
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::ResetLogFile(){
	string CleanStr;
	// clear file log
	CleanStr = "rm -f " + g_System_logDirectory + "/" + g_Username + "@" + g_Domain;
	system(CleanStr.c_str());
	//cout << "CleanStr: " << CleanStr << endl;
	
	FILE *fn;
	string sessionInfoPath;
	
	sessionInfoPath = g_System_WorkspaceDir + "/" + g_Username + ".info";
	//cout << "sessionInfoPath: " << sessionInfoPath << endl;
	
	fn = fopen(sessionInfoPath.c_str(), "wb");
	if (fn == NULL) {
		fclose(fn);
		return;
	}
	
	if(g_assignmentPtr.size() > 0) {
		g_assignmentPtr.clear();
	}
	
	if(g_captionImg.size() > 0) {
		g_captionImg.clear();
	}
	
	fprintf(fn, "#Audience Media Header Record#\r\n");
	//fprintf(fn, "Session id : %s\r\n", n_mSessionID.c_str());
	fprintf(fn, "Unlock stories: %s\r\n", g_UnlockStories.c_str());
	
	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.zip";
	system(CleanStr.c_str());
	
	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.jpg";
	system(CleanStr.c_str());
	
//	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.icml";
//	system(CleanStr.c_str());
	
//	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.idml";
//	system(CleanStr.c_str());
	
//	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.indd";
//	system(CleanStr.c_str());
	
	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.icma";
	system(CleanStr.c_str());
	
	CleanStr = "cd " + g_System_WorkspaceDir + " && rm -rf " + "*.idlk";
	system(CleanStr.c_str());
	
	fclose(fn);
}

/********************************************************************************************************************
 *****Function: RemoveInfoTextframe
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::RemoveInfoTextframe()
{
	do {
		IDocument* document = Utils<ILayoutUIUtils>()->GetFrontDocument();
		string tmp;
		UIDRef storyInfo = AMPUtils::GetIDTextFrameInfo(document, tmp);
		if(storyInfo == UIDRef::gNull)
		{
			break;
		}
		
		AMPManipulateTextFrame instance;
		
		UIDRef pageItemRef = instance.QueryGraphicFrameRef(storyInfo);
		if(pageItemRef != UIDRef::gNull)
		{
			cout << "+++ this is frame need process" << endl;
			bool16 result = kFalse;
			ErrorCode status = kFailure;
			Utils<IPageItemTypeUtils> pageItemTypeUtils;
			if (pageItemTypeUtils && pageItemTypeUtils->IsTextFrame(pageItemRef)) {
				result = kTrue;
			}
			if(result == kFalse)
			{
				break;
			}
			InterfacePtr<ICommand> deleteCmd(CmdUtils::CreateCommand(kDeleteCmdBoss));
			ASSERT(deleteCmd);
			if (!deleteCmd) {
				break;
			}
			deleteCmd->SetItemList(UIDList(pageItemRef));
			status = CmdUtils::ProcessCommand(deleteCmd);
			if (status == kSuccess) {
				storyInfo = UIDRef::gNull;
			}
			break;
		}
		/*
		SDKLayoutHelper layoutHelper;
		
		InterfacePtr<ISpreadList> spreadList(document, UseDefaultIID());
		if(!spreadList) {
			break;
		}
		UIDRef docRef = GetUIDRef(document);
		UIDRef spreadRef = UIDRef(docRef.GetDataBase(), spreadList->GetNthSpreadUID(0));
		
		InterfacePtr<ISpread> spread(spreadRef, UseDefaultIID());
		ASSERT(spread);
		if(!spread) {
			break;
		}
		IDataBase* database = ::GetDataBase(document);
		UIDList pageItemList(database);
		spread->GetItemsOnPage( 0, &pageItemList, kFalse,kTrue);	//info textframe is always on the top of page 1
		int32 pageItemListLength = pageItemList.Length();
		for (int32 j = 0; j < pageItemListLength; j++ )
		{
			cout << "+++ pageItemRef:"<< j << endl;
			UIDRef pageItemRef = pageItemList.GetRef(j);
			InterfacePtr<IGraphicFrameData> graphicFrameData(pageItemRef, UseDefaultIID());
			if(!graphicFrameData) {
				break;
			}
			bool16 hasContent = graphicFrameData->IsGraphicFrame();
			if(hasContent == kTrue) {
				cout << "+++ pageItemRef: IS GRAPHICFRAME" << endl;
				UIDRef _storyUIDRef = layoutHelper.GetTextModelRef(graphicFrameData);
				if(_storyUIDRef == storyInfo)
				{
					cout << "+++ this is frame need process" << endl;
					bool16 result = kFalse;
					ErrorCode status = kFailure;
					Utils<IPageItemTypeUtils> pageItemTypeUtils;
					if (pageItemTypeUtils && pageItemTypeUtils->IsTextFrame(pageItemRef)) {
						result = kTrue;
					}
					if(result == kFalse)
					{
						break;
					}
					InterfacePtr<ICommand> deleteCmd(CmdUtils::CreateCommand(kDeleteCmdBoss));
					ASSERT(deleteCmd);
					if (!deleteCmd) {
						break;
					}
					deleteCmd->SetItemList(UIDList(pageItemRef));
					status = CmdUtils::ProcessCommand(deleteCmd);
					if (status == kSuccess) {
						storyInfo = UIDRef::gNull;
					}
					break;
				}
			}
		}
		*/
		cout << "====end delete texframe" << endl;

	}while(kFalse);
}

/********************************************************************************************************************
 *****Function: IssueListRefresh
 *****Creator:  Toan Nguyen
 *****IN:
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void AMPUtils::IssueListRefresh()
{
	do
	{
		string displayString, SetDefaultPath;
		//cout << "BrowseIssueRefresh()" << endl;
		
		// Get the application interface and the DialogMgr.	
		InterfacePtr<IApplication> application(GetExecutionContextSession()->QueryApplication());
		if (application == nil)
		{
			//cout << "BscDlgActionComponent::DoDialog: application invalid" << endl;
			break;
		}
		InterfacePtr<IDialogMgr> dialogMgr(application, UseDefaultIID());
		if (dialogMgr == nil)
		{ 
			//cout << "BscDlgActionComponent::DoDialog: dialogMgr invalid" << endl;
			break;
		}
		// Load the plug-in's resource.
		PMLocaleId nLocale = LocaleSetting::GetLocale();
		RsrcSpec dialogSpec
		(
		 nLocale,					// Locale index from PMLocaleIDs.h. 
		 kAMPPluginID,				// Our Plug-in ID from BasicDialogID.h. 
		 kViewRsrcType,				// This is the kViewRsrcType.
		 kBscSlDlgIssuesDialogResourceID,			// Resource ID for our dialog.
		 kTrue						// Initially visible.
		 );
		
		// CreateNewDialog takes the dialogSpec created above, and also
		// the type of dialog being created (kMovableModal).
		IDialog* dialog = dialogMgr->CreateNewDialog(dialogSpec, IDialog::kMovableModal);
		if (dialog == nil)
		{ 
			//ASSERT_FAIL("BscDlgActionComponent::DoDialog: can't create dialog"); 
			break;
		}
		
		InterfacePtr<IPanelControlData> iPanelControlData(dialog, UseDefaultIID());
		ASSERT(iPanelControlData);
		if(iPanelControlData==nil) {
			//cout << "panelControlData invalid" << endl;
			break;
		}
		
		IControlView* iWidgetView = iPanelControlData->FindWidget(kAMPCheckOutButtonWidgetID);
		ASSERT(iWidgetView);
		if(!iWidgetView) {
			//cout << "error 2" << endl;
			break;
		}
		
		// Get Next and Previous buttons
		IControlView* nextButtonView = 
		iPanelControlData->FindWidget(kPreviewImageNextWidgetID);
		ASSERT(nextButtonView);
		if(!nextButtonView) {
			//cout << "error 3" << endl;
			break;
		}
		
		IControlView* prevButtonView = 
		iPanelControlData->FindWidget(kPreviewImagePreviousWidgetID);
		ASSERT(prevButtonView);
		if(!prevButtonView) {
			//cout << "error 4" << endl;
			break;
		}
		IControlView* radioButtonPanel = iPanelControlData->FindWidget(kAMPClusterPanelWidgetID);
		ASSERT(radioButtonPanel);
		if(!radioButtonPanel)
		{
			//cout << "error 5" << endl;
			break;
		}
		
		IControlView* RadioLowchildView = iPanelControlData->FindWidget(kBscRadioLowResWidgetID);
		if (RadioLowchildView == nil)
		{
			//cout << "error RadioLowchildView" << endl;
			break;
		}
		InterfacePtr<ITriStateControlData> triDataLow(RadioLowchildView, UseDefaultIID());
		if (triDataLow)
		{
			//cout << "error triData" << endl;
			triDataLow->SetState(ITriStateControlData::kSelected, nil, nil);
		}
		
		IControlView* RadioHighchildView = iPanelControlData->FindWidget(kBscRadioHighResWidgetID);
		if (RadioHighchildView == nil)
		{
			//cout << "error RadioLowchildView" << endl;
			break;
		}
		InterfacePtr<ITriStateControlData> triDataHigh(RadioHighchildView, UseDefaultIID());
		if (triDataHigh)
		{
			//cout << "error triDataHigh" << endl;
			triDataHigh->SetState(ITriStateControlData::kUnselected, nil, nil);
		}
		
		IControlView* textMessageWidget = iPanelControlData->FindWidget(kAMPIssuesTextMessageWidgetID);
		ASSERT(textMessageWidget);
		if(!textMessageWidget)
		{
			//cout << "error 6" << endl;
			break;
		}
		
		InterfacePtr<ITextControlData> textControlData(textMessageWidget, UseDefaultIID());
		ASSERT(textControlData);
		if(!textControlData)
		{
			//cout << "error 7" << endl;
			break;
		}
		IControlView* iPreviewMainView = iPanelControlData->FindWidget(kAMPGroupViewPanelWidgetID);
		ASSERT(iPreviewMainView);
		if(!iPreviewMainView) {
			break;
		}
		
		IControlView* iLeftRightView = iPanelControlData->FindWidget(kAMPGroupPanelWidgetID);
		ASSERT(iLeftRightView);
		if(!iLeftRightView) {
			break;
		}
		
		IControlView* iViewWidgetView = 
		iPanelControlData->FindWidget(kAMPCustomPanelViewWidgetID);
		ASSERT(iViewWidgetView);
		if(!iViewWidgetView) {
			cout << "iViewWidgetView is nil" << endl;  
			break;
		}
		
		// setup init again for Browse Issue
		{
			iWidgetView->Disable(kTrue);
			nextButtonView->Disable(kTrue);
			prevButtonView->Disable(kTrue);
			radioButtonPanel->Disable(kTrue);
			displayString = "Preview";
			g_Resolution = "low";
			SetDefaultPath =  g_ImagePreview;
			
			textControlData->SetString(displayString.c_str());
			
			// display page preview at center
			iLeftRightView->Disable();
			iLeftRightView->Hide();
			
			iPreviewMainView->Enable(TRUE, TRUE);
			iPreviewMainView->Show();
			iViewWidgetView->Enable(TRUE, TRUE);
			iViewWidgetView->Show();
		}
		
		PMString path(SetDefaultPath.c_str());
		SDKFileHelper fileHelper(path);
		IDFile xFile = fileHelper.GetIDFile();
		
		// below, if we could find the stream, we'll set this true
		InterfacePtr<IPMStream> iDataFileStream(StreamUtil::CreateFileStreamReadLazy(xFile));
		// If nil, we couldn't have opened this
		if (iDataFileStream == nil)
		{
			//cout << "iDataFileStream is nil" << endl;
			break;
		}
		
		iDataFileStream->Close();
		
		InterfacePtr<ISysFileData> iSysFileData(iViewWidgetView, IID_ISYSFILEDATA);
		ASSERT(iSysFileData);
		if(!iSysFileData)
		{
			//cout << "iSysFileData is nil" << endl;  
			break;
		}
		// set display default preview image
		{
			iSysFileData->Set(xFile);
			iViewWidgetView->Invalidate();
		}
		
	} while(kFalse);
}


/********************************************************************************************************************
 *****Function: GetIDTextFrameInfo
 *****Creator:  Toan Nguyen
 *****IN:IDocument *iDocument
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
UIDRef AMPUtils::GetIDTextFrameInfo(IDocument *iDocument, string &content) {
	do {
		
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			//cout << "storyList == nil" << endl;
			break;
		}
		string tempInfo = "Plugin_info::AudienceMediaInDesignPluginInformation::Plugin_info";
		int textModelCount = storyList->GetAllTextModelCount();
		for (int32 i = 0; i < textModelCount; i++ )
		{
			//cout << "----->story: " << i << endl;
			TextStory_StoryAccess storyAccess = storyList->GetNthTextModelAccess(i);
			
			// Get the text model of the story.
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
			ASSERT(textModel);
			if (!textModel) {
				break;
			}
			int32 totalLength = textModel->TotalLength();
			//int32 primaryStoryThreadSpan = textModel->GetPrimaryStoryThreadSpan();
			
			TextIterator begin(textModel, 0);
			TextIterator end(textModel, totalLength-1);
			TextIterator limit(textModel, tempInfo.length()+1);
			PMString str("");
			TextIterator iter = begin;
			for (iter = begin; iter != end; iter++)
			{ 
				// get all content of textmodel
				const UTF32TextChar characterCode = *iter;
				PMString character;
				character.AppendW(characterCode);
				TextIndex position = iter.Position();
				str.Append(character.GrabCString());
				if(iter >= limit){
					break;	
				}
			}
			
			if(iter < limit){
				continue;
			}
			string iContent = str.GrabCString();
			// find textframe stores info 
			size_t start_info = iContent.find("Plugin_info::");
			size_t end_info = iContent.find("::Plugin_info");
			if (start_info != string::npos && end_info != string::npos) {
				//cout << "info of package is already exsited" << endl;
				str.clear();
				for (iter = begin; iter != end; iter++)
				{ 
					// get all content of textmodel
					const UTF32TextChar characterCode = *iter;
					PMString character;
					character.AppendW(characterCode);
					TextIndex position = iter.Position();
					str.Append(character.GrabCString());
				}
				content = str.GrabCString();
				return storyUIDRef;
			}
		}
	}while(kFalse);
	content = "";
	return UIDRef::gNull;
}

void AMPUtils::DoExportIDML() {
	
	if(Utils<ILayoutUIUtils>() == nil)
	{
		return;
	}
	IDocument* document = Utils<ILayoutUIUtils>()->GetFrontDocument();
	// +precondition
	ASSERT(document);
	if(!document) {
		cout << "Cannot load document" << endl;
		return;
	}
	PMString docName; 
	document->GetName(docName);

	string nameStr = docName.GrabCString();
	UIDRef docRef = GetUIDRef(document); 
	
	if (g_DocName.length() > 0 && g_DocName.compare(nameStr) == 0) {
		
		string IDMLexport = g_SDK_WorkspaceDir + ":" + g_Package_id + ".idml";
		
		PMString fileLocation(IDMLexport.c_str());
		IDFile sysIDMLFile(fileLocation);
		AMPDocument::DoIDMLFileCreating(docRef, sysIDMLFile, FALSE);
	}
}

void AMPUtils::QueryFrameRef(IDocument *iDocument) {
	
	if(g_assignmentPtr.size() <= 0) {
		return;
	}
	AMPManipulateTextFrame instance;
	do {
		
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(iDocument, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			break;
		}
		
		for (int n = 0; n < g_assignmentPtr.size(); n++) {
			string storyUID = g_assignmentPtr[n].storyUID;
			
			for (int32 i = 0; i < storyList->GetAllTextModelCount(); i++ )
			{
				UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
				InterfacePtr<ITextModel> textModel(storyUIDRef, UseDefaultIID());
				ASSERT(textModel);
				if (!textModel) {
					break;
				}
				
				InterfacePtr<IIDMLComponentName> compName(storyUIDRef, UseDefaultIID());
				WideString nameStr;
				compName->Get(nameStr);
				string tmp;
				StringUtils::ConvertWideStringToUTF8(nameStr, tmp);
				if(storyUID == tmp){
					//cout << "assigmnet story's name:" << tmp << endl;
					g_assignmentPtr[n].story_assignment = storyUIDRef;
					g_assignmentPtr[n].frameUIDRef = instance.QueryGraphicFrameRef(storyUIDRef);
					break;
				}
			} // iterate stories
			//cout << "assigmnet storyUID:" << storyUID << endl;
		}
		
		
	} while (kFalse);
}


int32 g_startTime = 0;
int32 g_EndTime = 0;

string AMPUtils::CalculateTimer(int Startup){
	int32 hour, minute, second;
	time_t rawtime;
	struct tm * timeinfo;
	time ( &rawtime );
	timeinfo = localtime ( &rawtime );

	//Read Hour minute and second
	hour = timeinfo->tm_hour;
	minute = timeinfo->tm_min;
	second = timeinfo->tm_sec;
	
	if (Startup == TRUE) {
		g_startTime = hour * 3600 + minute * 60 + second;
		g_EndTime = g_startTime;
	}else {
		g_EndTime = hour * 3600 + minute * 60 + second;
	}
	
	int32 TimerUp = g_EndTime - g_startTime;
	string _time_in_;
	stringstream _time_out_;
	_time_out_ << TimerUp;
	_time_in_ = _time_out_.str();
	return _time_in_;
}


void AMPUtils::TestIconFrame(int32 status)
{
	cout << "TestIconFrame" << endl;
	AMPManipulateTextFrame instance;
	do {
		if(Utils<ILayoutUIUtils>() == nil)
		{
			return;
		}
		IDocument* document = Utils<ILayoutUIUtils>()->GetFrontDocument();
		ASSERT(document);
		if(!document) {
			return;
		}
		// Get the list of stories in this document
		InterfacePtr<IStoryList> storyList(document, UseDefaultIID());
		ASSERT(storyList);
		if (!storyList) {
			break;
		}
		
		for (int32 i = 0; i < storyList->GetAllTextModelCount(); i++ )
		{
			UIDRef storyUIDRef = storyList->GetNthTextModelUID(i);
			FrmLblInfo frmLblInfo;
			frmLblInfo.status = status;
			UIDRef pageItemRef = instance.QueryGraphicFrameRef(storyUIDRef);
			if(pageItemRef !=  UIDRef::gNull) {
				Utils<IFrmLblDataFacade>()->UpdateFrameLabelProperties(UIDList(pageItemRef), frmLblInfo);
				cout << "UpdateFrameLabelProperties storyUID:" << storyUIDRef << endl;
			}
			//
		} // iterate stories
		//cout << "end add stories icon:" << endl;
		
	} while(false);
}

void AMPUtils::AddToAssignment()
{	
	FrmLblInfo frmLblInfo;
	frmLblInfo.status = 1;
	do {
		for (int i = 0; i < g_assignmentPtr.size(); i++) {
			pt_assignStr iStorylinkRef = g_assignmentPtr[i];
			UIDRef frameUIDRef = iStorylinkRef.frameUIDRef;
			if(frameUIDRef !=  UIDRef::gNull) {
				Utils<IFrmLblDataFacade>()->UpdateFrameLabelProperties(UIDList(frameUIDRef), frmLblInfo);
				AMPUtils::InspectThreadedTextFrames(frameUIDRef, frmLblInfo);
			}
		}
		
	} while(false);
}


void AMPUtils::UpdateStatusProperties(UIDRef& frameUIDRef, int32 status){

	if(frameUIDRef == UIDRef::gNull)
		return;
	
	FrmLblInfo frmLblInfo;
	frmLblInfo.status = status;
	Utils<IFrmLblDataFacade>()->UpdateFrameLabelProperties(UIDList(frameUIDRef), frmLblInfo);
	AMPUtils::InspectThreadedTextFrames(frameUIDRef, frmLblInfo);
}


void AMPUtils::InspectThreadedTextFrames(const UIDRef& graphicFrameUIDRef, FrmLblInfo& frmLblInfo)
{
	do {
		// Report information on the given graphic frame.
		// Report information on the frames that preceed the given frame.
		UIDRef previousGraphicFrameUIDRef = GetPreviousGraphicFrame(graphicFrameUIDRef);
		if (previousGraphicFrameUIDRef != UIDRef::gNull) {
			do {
				Utils<IFrmLblDataFacade>()->UpdateFrameLabelProperties(UIDList(previousGraphicFrameUIDRef), frmLblInfo);
				previousGraphicFrameUIDRef = GetPreviousGraphicFrame(previousGraphicFrameUIDRef);
			} while(previousGraphicFrameUIDRef != UIDRef::gNull);
		}
		
		// Report information on the frames that succeed the given frame.
		UIDRef nextGraphicFrameUIDRef = GetNextGraphicFrame(graphicFrameUIDRef);
		if (nextGraphicFrameUIDRef != UIDRef::gNull) {
			do {
				Utils<IFrmLblDataFacade>()->UpdateFrameLabelProperties(UIDList(nextGraphicFrameUIDRef), frmLblInfo);
				nextGraphicFrameUIDRef = GetNextGraphicFrame(nextGraphicFrameUIDRef);
			} while(nextGraphicFrameUIDRef != UIDRef::gNull);
		}
		
	} while(false);
}


UIDRef AMPUtils::QueryPreviousGraphicFrame(const UIDRef& graphicFrameUIDRef)
{
	return GetPreviousGraphicFrame(graphicFrameUIDRef);
}


UIDRef AMPUtils::GetPreviousGraphicFrame(const UIDRef& graphicFrameUIDRef)
{
	UIDRef result = UIDRef::gNull;
	do {
		InterfacePtr<IMultiColumnTextFrame> mcf(graphicFrameUIDRef.GetDataBase(), GetTextContentUID(graphicFrameUIDRef), UseDefaultIID());
		ASSERT(mcf != nil);
		if (mcf == nil) {
			break;
		}
		InterfacePtr<IFrameList> frameList(mcf->QueryFrameList());
		ASSERT(frameList);
		if (!frameList) {
			break;
		}
		int32 mcfFirstFrameIndex = frameList->GetFrameIndex(mcf->GetUIDInFrameList(kFalse));
		if (mcfFirstFrameIndex == 0) {
			// The given graphic frame contains the first frame in the frame list.
			// There is no previous frame.
			break;
		}
		// Determine the graphic frame that contains the previous kFrameItemBoss in the frame list.
		InterfacePtr<ITextFrameColumn> previousTFC(frameList->QueryNthFrame(mcfFirstFrameIndex-1));
		if (!previousTFC) {
			break;
		}
		UIDRef previousGraphicFrameRef = GetGraphicFrameRef(previousTFC, kTrue);
		result = previousGraphicFrameRef;
	} while (false);
	return result;
}


UIDRef AMPUtils::GetNextGraphicFrame(const UIDRef& graphicFrameUIDRef)
{
	UIDRef result = UIDRef::gNull;
	do {
		InterfacePtr<IMultiColumnTextFrame> mcf(graphicFrameUIDRef.GetDataBase(), GetTextContentUID(graphicFrameUIDRef), UseDefaultIID());
		ASSERT(mcf != nil);
		if (mcf == nil) {
			break;
		}
		InterfacePtr<IFrameList> frameList(mcf->QueryFrameList());
		ASSERT(frameList);
		if (!frameList) {
			break;
		}
		int32 mcfLastFrameIndex = frameList->GetFrameIndex(mcf->GetUIDInFrameList(kTrue));
		if (mcfLastFrameIndex == frameList->GetFrameCount() - 1) {
			// The given graphic frame contains the last frame in the frame list.
			// There is no next frame.
			break;
		}
		// Determine the graphic frame that contains the next kFrameItemBoss in the frame list.
		InterfacePtr<ITextFrameColumn> nextTFC(frameList->QueryNthFrame(mcfLastFrameIndex+1));
		if (!mcf) {
			break;
		}
		UIDRef nextGraphicFrameRef = GetGraphicFrameRef(nextTFC, kTrue);
		result = nextGraphicFrameRef;
	} while (false);
	return result;
}



UIDRef AMPUtils::GetGraphicFrameRef(const InterfacePtr<ITextFrameColumn>& textFrameColumn, const bool16 isTOPFrameAllowed)
{
	UIDRef result = UIDRef::gNull;
	
	do {
		ASSERT(textFrameColumn);
		if (!textFrameColumn) {
			break;
		}
		
		// Check for a regular text frame by going up
		// the hierarchy till we find a parent object
		// that aggregates IGraphicFrameData. This is
		// the graphic frame that contains the text content.
		UIDRef graphicFrameDataUIDRef = UIDRef::gNull;
		InterfacePtr<IHierarchy> child(textFrameColumn, UseDefaultIID());
		if (child == nil) {
			break;
		}
		do {
			InterfacePtr<IHierarchy> parent(child->QueryParent());
			if (parent == nil) {
				break;
			}
			InterfacePtr<IGraphicFrameData> graphicFrameData(parent, UseDefaultIID());
			if (graphicFrameData != nil) {
				// We have a text frame.
				graphicFrameDataUIDRef = ::GetUIDRef(graphicFrameData);
				break;
			}
			child = parent;
		} while(child != nil);
		
		if (graphicFrameDataUIDRef == UIDRef::gNull) {
			break;
		}
		
		InterfacePtr<ITOPSplineData> topSplineData(graphicFrameDataUIDRef, UseDefaultIID());
		if (topSplineData) {
			// We have a text on a path frame.
			if (isTOPFrameAllowed == kTrue) {
				// Return the text on a path frame
				result = graphicFrameDataUIDRef;
			}
			else {
				// Return the graphic frame associated with the text on a path frame.
				UID mainSplineItemUID = topSplineData->GetMainSplineItemUID();
				ASSERT(mainSplineItemUID != kInvalidUID);
				result = UIDRef(graphicFrameDataUIDRef.GetDataBase(), mainSplineItemUID);
			}
		}
		else {
			// We have a normal graphic frame.
			result = graphicFrameDataUIDRef;
		}
		
	} while(false);
	
	return result;
	
}


UID AMPUtils::GetTextContentUID(const UIDRef& graphicFrameUIDRef)
{
	UID result = kInvalidUID;
	InterfacePtr<IGraphicFrameData> graphicFrameData(graphicFrameUIDRef, UseDefaultIID());
	if (graphicFrameData) {
		result = graphicFrameData->GetTextContentUID();
	}
	return result;
}


bool8 AMPUtils::PostCaptionImg(UIDRef captionUIDRef, string caption_name)
{
	bool8 resCaption = kFalse;
	
	do {
		for(int32 n = 0; n < g_captionImg.size(); n++){
			if(caption_name == g_captionImg[n].caption_self)
			{
				cout << "+++++story_self:" << caption_name << endl;
				AMPUtils::ExportStoryToICML(captionUIDRef, caption_name);
				
				// do http request to post data 
				string pathFile = g_System_WorkspaceDir + "/" + caption_name + ".icml";
				HTTPRequestHelper::PostCaptionContentToCMS(caption_name, pathFile);
				resCaption = kTrue;
			}
		}
	}while(kFalse);
	return resCaption;
}